mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-01 05:18:00 +01:00
+ Added the Projectile check to prevent various cheats
+ Added the AutoSign check to prevent players from spamming signs + Added the Tracker check to prevent players from staying too much time in the air = Improved the FastBreak check (should work with various plugins) = Improved the FastPlace check (shouldn't throw any false positive)
This commit is contained in:
parent
dbfe983c1e
commit
b08db5bd4b
@ -240,6 +240,15 @@
|
||||
|
||||
- nocheatplus.checks.blockplace.direction
|
||||
Don't force players to look at the blocks that they try to place.
|
||||
|
||||
- nocheatplus.checks.blockplace.projectile
|
||||
Allows the player to throw projectiles very quickly, like expbottles, eggs,
|
||||
monster eggs, eyes of ender, ender pearls. This is usually used by griefers
|
||||
to level up very quickly or to crash the server by spawning too much mobs.
|
||||
|
||||
- nocheatplus.checks.blockplace.autosign
|
||||
Allows the player to place multiple signs with the same text. This is usually
|
||||
used by griefers to place quickly a lot of signs with their signature.
|
||||
|
||||
|
||||
--------------------- INVENTORY Permissions for CHECKS -------------------------
|
||||
@ -597,6 +606,20 @@
|
||||
fall distance in blocks that the player tried to avoid. It gets
|
||||
increased every time that the player fails the check, and decreased
|
||||
over time if the player doesn't fail the check.
|
||||
|
||||
TRACKER:
|
||||
This is an entire subsection dedicated to a recently introduced check
|
||||
specially designed to prevent players from staying in the air longer
|
||||
than a defined value.
|
||||
|
||||
active:
|
||||
Should players get checked for this type of movement related hacks at
|
||||
all. If deactivated, player may stay in the air without being noticed
|
||||
by NoCheat+.
|
||||
|
||||
maxtime:
|
||||
The maximum interval (in milliseconds) before kicking the player who
|
||||
flies (it takes less than 6000 ms to fall from Y = 256 to Y = 0);
|
||||
|
||||
FLYING:
|
||||
This is an entire subsection dedicated to the "moving.flying" check.
|
||||
@ -837,7 +860,7 @@
|
||||
combined with placing a lot of blocks in a certain shape.
|
||||
|
||||
active:
|
||||
Should players get checked for this type of hack
|
||||
Should players get checked for this type of hack.
|
||||
|
||||
precision:
|
||||
How strict should NoCheatPlus be when comparing the players line of view
|
||||
@ -859,6 +882,26 @@
|
||||
the distance in Blocks between the line of view of the player and the
|
||||
block. It increases with every failure and decreases with every
|
||||
successful block placement.
|
||||
|
||||
4) PROJECTILE
|
||||
|
||||
Players may throw projectiles (experience bottles, eggs, monster eggs,
|
||||
eyes of ender, ender pearls) really quickly in order to crash the server.
|
||||
|
||||
active:
|
||||
Should players get checked for this type of hack.
|
||||
|
||||
interval:
|
||||
The time (in milliseconds) between each thrown projectile. It takes
|
||||
more than 150 ms if the player is keeping its right button pressed.
|
||||
|
||||
actions:
|
||||
What should happen if a player fails this check. Default is to prevent
|
||||
the placing of the block ("cancel" it) and after repeated/more severe
|
||||
offenses to log a message and kick the player. The Violation Level (VL)
|
||||
for this check is the interval elapsed subtracted to the interval defined
|
||||
in the configuration's file; It increases with every failure and decreases
|
||||
with every successfully thrown projectile.
|
||||
|
||||
|
||||
------------------------------- CHAT Subsection --------------------------------
|
||||
|
@ -73,6 +73,10 @@ permissions:
|
||||
description: Allow a player to place blocks at maximum range (about 6-7 blocks)
|
||||
nocheatplus.checks.blockplace.direction:
|
||||
description: Allow a player to place blocks outside their line of view
|
||||
nocheatplus.checks.blockplace.projectile:
|
||||
description: Allow a player to throw projectiles very quickly
|
||||
nocheatplus.checks.blockplace.autosign:
|
||||
description: Allow a player to create multiple signs with the same text
|
||||
nocheatplus.checks.chat:
|
||||
description: Allow the player to bypass all chat checks
|
||||
children:
|
||||
|
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
|
||||
<!-- Informations -->
|
||||
<name>NoCheatPlus</name>
|
||||
<version>3.5.3</version>
|
||||
<version>3.5.4</version>
|
||||
<description>Detect and fight the exploitation of various flaws/bugs in Minecraft.</description>
|
||||
<url>http://dev.bukkit.org/server-mods/nocheatplus</url>
|
||||
|
||||
|
@ -15,6 +15,8 @@ import me.neatmonster.nocheatplus.config.Permissions;
|
||||
public class BlockBreakConfig implements ConfigItem {
|
||||
|
||||
public final boolean fastBreakCheck;
|
||||
public final int fastBreakIntervalSurvival;
|
||||
public final int fastBreakIntervalCreative;
|
||||
public final ActionList fastBreakActions;
|
||||
|
||||
public final boolean reachCheck;
|
||||
@ -32,6 +34,8 @@ public class BlockBreakConfig implements ConfigItem {
|
||||
public BlockBreakConfig(final NoCheatPlusConfiguration data) {
|
||||
|
||||
fastBreakCheck = data.getBoolean(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK);
|
||||
fastBreakIntervalSurvival = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVALSURVIVAL);
|
||||
fastBreakIntervalCreative = data.getInt(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVALCREATIVE);
|
||||
fastBreakActions = data.getActionList(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS, Permissions.BLOCKBREAK_FASTBREAK);
|
||||
reachCheck = data.getBoolean(ConfPaths.BLOCKBREAK_REACH_CHECK);
|
||||
reachDistance = 535D / 100D;
|
||||
|
@ -15,9 +15,12 @@ public class BlockBreakData implements DataItem {
|
||||
public double directionVL = 0.0D;
|
||||
public double noswingVL = 0.0D;
|
||||
|
||||
// Used the know when the player has broke his previous block
|
||||
// Used to know when the player has broken his previous block
|
||||
public long lastBreakTime = 0;
|
||||
|
||||
// Used to know if the previous event was refused
|
||||
public boolean previousRefused = false;
|
||||
|
||||
// Used for the penalty time feature of the direction check
|
||||
public long directionLastViolationTime = 0;
|
||||
|
||||
|
@ -8,8 +8,6 @@ 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 {
|
||||
|
||||
@ -19,297 +17,39 @@ 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));
|
||||
// Get the minimum break time for the player's game mode
|
||||
int breakTime = cc.fastBreakIntervalSurvival;
|
||||
if (player.getPlayer().getGameMode() == GameMode.CREATIVE)
|
||||
breakTime = cc.fastBreakIntervalCreative;
|
||||
|
||||
// Elapsed time since the previous block was broken
|
||||
final long elapsedTime = Math.round((System.nanoTime() - data.lastBreakTime) / Math.pow(10, 6));
|
||||
final long elapsedTime = System.currentTimeMillis() - data.lastBreakTime;
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
// Has the player broke blocks too quickly
|
||||
// Has the player broken the blocks too quickly
|
||||
if (data.lastBreakTime != 0 && elapsedTime < breakTime) {
|
||||
// He failed, increase vl and statistics
|
||||
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);
|
||||
} else
|
||||
if (data.previousRefused) {
|
||||
// He failed, increase vl and statistics
|
||||
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);
|
||||
}
|
||||
data.previousRefused = true;
|
||||
} else {
|
||||
// Reward with lowering of the violation level
|
||||
data.fastBreakVL *= 0.90D;
|
||||
data.previousRefused = false;
|
||||
}
|
||||
|
||||
data.lastBreakTime = System.nanoTime();
|
||||
data.lastBreakTime = System.currentTimeMillis();
|
||||
|
||||
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) {
|
||||
|
||||
@ -318,34 +58,4 @@ public class FastBreakCheck extends BlockBreakCheck {
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,10 +9,17 @@ import me.neatmonster.nocheatplus.NoCheatPlusPlayer;
|
||||
import me.neatmonster.nocheatplus.config.ConfigurationCacheStore;
|
||||
import me.neatmonster.nocheatplus.config.Permissions;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
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.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
/**
|
||||
* Central location to listen to Block-related events and dispatching them to
|
||||
@ -21,10 +28,11 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
*/
|
||||
public class BlockPlaceCheckListener implements Listener, EventManager {
|
||||
|
||||
private final FastPlaceCheck fastPlaceCheck;
|
||||
private final ReachCheck reachCheck;
|
||||
private final DirectionCheck directionCheck;
|
||||
private final NoCheatPlus plugin;
|
||||
private final FastPlaceCheck fastPlaceCheck;
|
||||
private final ReachCheck reachCheck;
|
||||
private final DirectionCheck directionCheck;
|
||||
private final ProjectileCheck projectileCheck;
|
||||
private final NoCheatPlus plugin;
|
||||
|
||||
public BlockPlaceCheckListener(final NoCheatPlus plugin) {
|
||||
|
||||
@ -33,6 +41,7 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
|
||||
fastPlaceCheck = new FastPlaceCheck(plugin);
|
||||
reachCheck = new ReachCheck(plugin);
|
||||
directionCheck = new DirectionCheck(plugin);
|
||||
projectileCheck = new ProjectileCheck(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,4 +101,80 @@ public class BlockPlaceCheckListener implements Listener, EventManager {
|
||||
if (cancelled)
|
||||
event.setCancelled(cancelled);
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void monsterEgg(final PlayerInteractEvent event) {
|
||||
|
||||
// We are only interested by monster eggs
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || event.getPlayer().getItemInHand() == null
|
||||
|| event.getPlayer().getItemInHand().getType() != Material.MONSTER_EGG)
|
||||
return;
|
||||
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
|
||||
final BlockPlaceConfig cc = BlockPlaceCheck.getConfig(player);
|
||||
final BlockPlaceData data = BlockPlaceCheck.getData(player);
|
||||
|
||||
// Do the actual check
|
||||
if (cc.projectileCheck && !player.hasPermission(Permissions.BLOCKPLACE_PROJECTILE)
|
||||
&& projectileCheck.check(player, data, cc))
|
||||
// If the check is positive, cancel the event
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void otherProjectiles(final ProjectileLaunchEvent event) {
|
||||
|
||||
// We are only interested by enderpears, endersignals, eggs, snowballs and expbottles
|
||||
if (event.getEntityType() != EntityType.ENDER_PEARL && event.getEntityType() != EntityType.ENDER_SIGNAL
|
||||
&& event.getEntityType() != EntityType.EGG && event.getEntityType() != EntityType.SNOWBALL
|
||||
&& event.getEntityType() != EntityType.THROWN_EXP_BOTTLE)
|
||||
return;
|
||||
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer((Player) event.getEntity().getShooter());
|
||||
final BlockPlaceConfig cc = BlockPlaceCheck.getConfig(player);
|
||||
final BlockPlaceData data = BlockPlaceCheck.getData(player);
|
||||
|
||||
// Do the actual check
|
||||
if (cc.projectileCheck && !player.hasPermission(Permissions.BLOCKPLACE_PROJECTILE)
|
||||
&& projectileCheck.check(player, data, cc))
|
||||
// If the check is positive, cancel the event
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the player places three times the same sign,
|
||||
* the sign will be destroyed and looted
|
||||
*
|
||||
* @param event
|
||||
* the SignChange event
|
||||
*/
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void sign(final SignChangeEvent event) {
|
||||
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer(event.getPlayer());
|
||||
final BlockPlaceData data = BlockPlaceCheck.getData(player);
|
||||
|
||||
// Check if the text is the same
|
||||
if (!event.getPlayer().hasPermission(Permissions.BLOCKPLACE_AUTOSIGN)
|
||||
&& event.getLine(0).equals(data.lastSignText[0]) && event.getLine(1).equals(data.lastSignText[1])
|
||||
&& event.getLine(2).equals(data.lastSignText[2]) && event.getLine(3).equals(data.lastSignText[3])
|
||||
&& data.lastSignText[0].equals(data.lastLastSignText[0])
|
||||
&& data.lastSignText[1].equals(data.lastLastSignText[1])
|
||||
&& data.lastSignText[2].equals(data.lastLastSignText[2])
|
||||
&& data.lastSignText[3].equals(data.lastLastSignText[3]))
|
||||
event.getBlock().breakNaturally();
|
||||
|
||||
// Save the text
|
||||
data.lastLastSignText[3] = data.lastSignText[3];
|
||||
data.lastLastSignText[2] = data.lastSignText[2];
|
||||
data.lastLastSignText[1] = data.lastSignText[1];
|
||||
data.lastLastSignText[0] = data.lastSignText[0];
|
||||
data.lastSignText[3] = event.getLine(3);
|
||||
data.lastSignText[2] = event.getLine(2);
|
||||
data.lastSignText[1] = event.getLine(1);
|
||||
data.lastSignText[0] = event.getLine(0);
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ public class BlockPlaceConfig implements ConfigItem {
|
||||
public final long directionPenaltyTime;
|
||||
public final double directionPrecision;
|
||||
|
||||
public final boolean projectileCheck;
|
||||
public final int projectileInterval;
|
||||
public final ActionList projectileActions;
|
||||
|
||||
public BlockPlaceConfig(final NoCheatPlusConfiguration data) {
|
||||
|
||||
fastPlaceCheck = data.getBoolean(ConfPaths.BLOCKPLACE_FASTPLACE_CHECK);
|
||||
@ -41,5 +45,10 @@ public class BlockPlaceConfig implements ConfigItem {
|
||||
directionPenaltyTime = data.getInt(ConfPaths.BLOCKPLACE_DIRECTION_PENALTYTIME);
|
||||
directionPrecision = data.getInt(ConfPaths.BLOCKPLACE_DIRECTION_PRECISION) / 100D;
|
||||
directionActions = data.getActionList(ConfPaths.BLOCKPLACE_DIRECTION_ACTIONS, Permissions.BLOCKPLACE_DIRECTION);
|
||||
|
||||
projectileCheck = data.getBoolean(ConfPaths.BLOCKPLACE_PROJECTILE_CHECK);
|
||||
projectileInterval = data.getInt(ConfPaths.BLOCKPLACE_PROJECTILE_INTERVAL);
|
||||
projectileActions = data.getActionList(ConfPaths.BLOCKPLACE_PROJECTILE_ACTIONS,
|
||||
Permissions.BLOCKPLACE_PROJECTILE);
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,14 @@ public class BlockPlaceData implements DataItem {
|
||||
public double fastPlaceVL = 0.0D;
|
||||
public double reachVL = 0.0D;
|
||||
public double directionVL = 0.0D;
|
||||
public double projectileVL = 0.0D;
|
||||
|
||||
// Used the know when the player has placed his previous block
|
||||
// Used to know when the player has placed his previous block
|
||||
public long lastPlaceTime = 0;
|
||||
|
||||
// Used to know if the previous event was refused
|
||||
public boolean previousRefused = false;
|
||||
|
||||
// Used for the penalty time feature of the direction check
|
||||
public long directionLastViolationTime = 0;
|
||||
|
||||
@ -28,4 +32,14 @@ public class BlockPlaceData implements DataItem {
|
||||
// For logging, remember the reachDistance that was calculated in the
|
||||
// reach check
|
||||
public double reachdistance;
|
||||
|
||||
// Store the two previous signs' text
|
||||
public String[] lastSignText = new String[] {"", "", "", ""};
|
||||
public String[] lastLastSignText = new String[] {"", "", "", ""};
|
||||
|
||||
// Used to store the last time a projectile was thrown
|
||||
public long lastProjectileTime = 0;
|
||||
|
||||
// Used to know if the previous projectile-thrown-event was refused
|
||||
public boolean previousProjectileRefused = false;
|
||||
}
|
||||
|
@ -19,17 +19,22 @@ public class FastPlaceCheck extends BlockPlaceCheck {
|
||||
|
||||
// Has the player placed blocks too quickly
|
||||
if (data.lastPlaceTime != 0 && System.currentTimeMillis() - data.lastPlaceTime < cc.fastPlaceInterval) {
|
||||
// He failed, increase vl and statistics
|
||||
data.fastPlaceVL += cc.fastPlaceInterval - System.currentTimeMillis() + data.lastPlaceTime;
|
||||
incrementStatistics(player, Id.BP_FASTPLACE, cc.fastPlaceInterval - System.currentTimeMillis()
|
||||
+ data.lastPlaceTime);
|
||||
if (data.previousRefused) {
|
||||
// He failed, increase vl and statistics
|
||||
data.fastPlaceVL += cc.fastPlaceInterval - System.currentTimeMillis() + data.lastPlaceTime;
|
||||
incrementStatistics(player, Id.BP_FASTPLACE, cc.fastPlaceInterval - System.currentTimeMillis()
|
||||
+ data.lastPlaceTime);
|
||||
|
||||
// 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.fastPlaceActions, data.fastPlaceVL);
|
||||
} else
|
||||
// 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.fastPlaceActions, data.fastPlaceVL);
|
||||
}
|
||||
data.previousRefused = true;
|
||||
} else {
|
||||
// Reward with lowering of the violation level
|
||||
data.fastPlaceVL *= 0.90D;
|
||||
data.previousRefused = false;
|
||||
}
|
||||
|
||||
data.lastPlaceTime = System.currentTimeMillis();
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
package me.neatmonster.nocheatplus.checks.blockplace;
|
||||
|
||||
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 ProjectileCheck extends BlockPlaceCheck {
|
||||
|
||||
public ProjectileCheck(final NoCheatPlus plugin) {
|
||||
super(plugin, "blockplace.projectile");
|
||||
}
|
||||
|
||||
public boolean check(final NoCheatPlusPlayer player, final BlockPlaceData data, final BlockPlaceConfig cc) {
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
// Has the player thrown the projectiles too quickly
|
||||
if (data.lastProjectileTime != 0
|
||||
&& System.currentTimeMillis() - data.lastProjectileTime < cc.projectileInterval) {
|
||||
if (data.previousProjectileRefused) {
|
||||
// He failed, increase vl and statistics
|
||||
data.projectileVL += cc.projectileInterval - System.currentTimeMillis() + data.lastProjectileTime;
|
||||
incrementStatistics(player, Id.BP_PROJECTILE, cc.projectileInterval - System.currentTimeMillis()
|
||||
+ data.lastProjectileTime);
|
||||
|
||||
// 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.projectileActions, data.projectileVL);
|
||||
}
|
||||
data.previousProjectileRefused = true;
|
||||
} else {
|
||||
// Reward with lowering of the violation level
|
||||
data.projectileVL *= 0.90D;
|
||||
data.previousProjectileRefused = false;
|
||||
}
|
||||
|
||||
data.lastProjectileTime = System.currentTimeMillis();
|
||||
|
||||
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).projectileVL);
|
||||
else
|
||||
return super.getParameter(wildcard, player);
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@ import me.neatmonster.nocheatplus.config.ConfigurationCacheStore;
|
||||
import me.neatmonster.nocheatplus.config.Permissions;
|
||||
import me.neatmonster.nocheatplus.data.PreciseLocation;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
@ -55,6 +57,52 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
morePacketsVehicleCheck = new MorePacketsVehicleCheck(plugin);
|
||||
waterWalkCheck = new WaterWalkCheck(plugin);
|
||||
|
||||
// Schedule a new synchronized repeating task repeated 20 times/s.
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
for (final Player bukkitPlayer : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
// Get some data about the player/config
|
||||
final NoCheatPlusPlayer player = plugin.getPlayer(bukkitPlayer);
|
||||
final MovingConfig cc = MovingCheck.getConfig(player);
|
||||
final MovingData data = MovingCheck.getData(player);
|
||||
|
||||
// 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 or if he has the required permission.
|
||||
if (!cc.tracker || cc.allowFlying || bukkitPlayer.getGameMode() == GameMode.CREATIVE
|
||||
|| bukkitPlayer.getAllowFlight() || bukkitPlayer.hasPermission(Permissions.MOVING_RUNFLY))
|
||||
return;
|
||||
|
||||
// If the player is in water or in vines, then do not run the check
|
||||
if (bukkitPlayer.getLocation().getBlock().getType() == Material.WATER
|
||||
|| bukkitPlayer.getLocation().getBlock().getType() == Material.STATIONARY_WATER
|
||||
|| bukkitPlayer.getLocation().getBlock().getType() == Material.VINE)
|
||||
return;
|
||||
|
||||
// If the player isn't falling or jumping
|
||||
if (Math.abs(bukkitPlayer.getVelocity().getY()) > 0.1D) {
|
||||
|
||||
// The player is falling/jumping, check if he was previously on the ground
|
||||
if (data.fallingSince == 0)
|
||||
data.fallingSince = System.currentTimeMillis();
|
||||
|
||||
// Check if he has stayed too much time in the air
|
||||
else if (System.currentTimeMillis() - data.fallingSince > cc.maxtime) {
|
||||
// He has, so now kick it
|
||||
bukkitPlayer.kickPlayer("Flying isn't enabled on this server!");
|
||||
data.fallingSince = 0;
|
||||
}
|
||||
} else // The player isn't falling/jumping, check if he was previous on the air
|
||||
if (data.fallingSince > 0)
|
||||
// Reset the timer
|
||||
data.fallingSince = 0;
|
||||
}
|
||||
}
|
||||
}, 1L, 1L);
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@ -187,7 +235,8 @@ public class MovingCheckListener implements Listener, EventManager {
|
||||
newTo = runningCheck.check(player, data, cc);
|
||||
|
||||
/** WATERWALK CHECK SECTION **/
|
||||
if (newTo == null && cc.waterWalkCheck && (!player.isCreative() || !cc.identifyCreativeMode)
|
||||
if (newTo == null && cc.waterWalkCheck && !cc.allowFlying && (!player.isCreative() || !cc.identifyCreativeMode)
|
||||
&& (!cc.runflyCheck || !player.hasPermission(Permissions.MOVING_FLYING))
|
||||
&& !player.hasPermission(Permissions.MOVING_WATERWALK))
|
||||
newTo = waterWalkCheck.check(player, data, cc);
|
||||
|
||||
|
@ -22,6 +22,10 @@ public class MovingConfig implements ConfigItem {
|
||||
public final boolean sneakingCheck;
|
||||
public final double sneakingSpeedLimit;
|
||||
public final ActionList actions;
|
||||
|
||||
public final boolean tracker;
|
||||
public final int maxtime;
|
||||
|
||||
public final boolean allowFlying;
|
||||
public final double flyingSpeedLimitVertical;
|
||||
public final double flyingSpeedLimitHorizontal;
|
||||
@ -62,6 +66,9 @@ public class MovingConfig implements ConfigItem {
|
||||
sneakingCheck = !data.getBoolean(ConfPaths.MOVING_RUNFLY_ALLOWFASTSNEAKING);
|
||||
actions = data.getActionList(ConfPaths.MOVING_RUNFLY_ACTIONS, Permissions.MOVING_RUNFLY);
|
||||
|
||||
tracker = data.getBoolean(ConfPaths.MOVING_RUNFLY_TRACKER_CHECK);
|
||||
maxtime = data.getInt(ConfPaths.MOVING_RUNFLY_TRACKER_MAXTIME);
|
||||
|
||||
allowFlying = data.getBoolean(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWALWAYS);
|
||||
flyingSpeedLimitVertical = data.getInt(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITVERTICAL) / 100D;
|
||||
flyingSpeedLimitHorizontal = data.getInt(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL) / 100D;
|
||||
|
@ -42,6 +42,9 @@ public class MovingData implements DataItem {
|
||||
public float fallDistance;
|
||||
public float lastAddedFallDistance;
|
||||
|
||||
// Keep in mind since when the player in falling/jumping
|
||||
public long fallingSince = 0L;
|
||||
|
||||
// Keep track of when "morePackets" last time checked and how much packets
|
||||
// a player sent and may send before failing the check
|
||||
public long morePacketsLastTime;
|
||||
|
@ -57,6 +57,10 @@ public abstract class ConfPaths {
|
||||
public final static String MOVING_RUNFLY_NOFALLAGGRESSIVE = MOVING_RUNFLY + "nofallaggressivemode";
|
||||
public final static String MOVING_RUNFLY_NOFALLACTIONS = MOVING_RUNFLY + "nofallactions";
|
||||
|
||||
private final static String MOVING_RUNFLY_TRACKER = MOVING_RUNFLY + "tracker.";
|
||||
public final static String MOVING_RUNFLY_TRACKER_CHECK = MOVING_RUNFLY_TRACKER + "active";
|
||||
public final static String MOVING_RUNFLY_TRACKER_MAXTIME = MOVING_RUNFLY_TRACKER + "maxtime";
|
||||
|
||||
private final static String MOVING_RUNFLY_FLYING = MOVING_RUNFLY + "flying.";
|
||||
public final static String MOVING_RUNFLY_FLYING_ALLOWALWAYS = MOVING_RUNFLY_FLYING + "allowflyingalways";
|
||||
public final static String MOVING_RUNFLY_FLYING_ALLOWINCREATIVE = MOVING_RUNFLY_FLYING
|
||||
@ -84,6 +88,8 @@ 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_INTERVALSURVIVAL = BLOCKBREAK_FASTBREAK + "intervalsurvival";
|
||||
public final static String BLOCKBREAK_FASTBREAK_INTERVALCREATIVE = BLOCKBREAK_FASTBREAK + "intervalcreative";
|
||||
public final static String BLOCKBREAK_FASTBREAK_ACTIONS = BLOCKBREAK_FASTBREAK + "actions";
|
||||
|
||||
private final static String BLOCKBREAK_REACH = BLOCKBREAK + "reach.";
|
||||
@ -117,6 +123,11 @@ public abstract class ConfPaths {
|
||||
public final static String BLOCKPLACE_DIRECTION_PENALTYTIME = BLOCKPLACE_DIRECTION + "penaltytime";
|
||||
public final static String BLOCKPLACE_DIRECTION_ACTIONS = BLOCKPLACE_DIRECTION + "actions";
|
||||
|
||||
private final static String BLOCKPLACE_PROJECTILE = BLOCKPLACE + "projectile.";
|
||||
public final static String BLOCKPLACE_PROJECTILE_CHECK = BLOCKPLACE_PROJECTILE + "active";
|
||||
public final static String BLOCKPLACE_PROJECTILE_INTERVAL = BLOCKPLACE_PROJECTILE + "interval";
|
||||
public final static String BLOCKPLACE_PROJECTILE_ACTIONS = BLOCKPLACE_PROJECTILE + "actions";
|
||||
|
||||
private final static String CHAT = CHECKS + "chat.";
|
||||
|
||||
private final static String CHAT_COLOR = CHAT + "color.";
|
||||
|
@ -53,6 +53,9 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
|
||||
set(ConfPaths.MOVING_RUNFLY_NOFALLAGGRESSIVE, true);
|
||||
set(ConfPaths.MOVING_RUNFLY_NOFALLACTIONS, "log:nofall:0:5:cif cancel");
|
||||
|
||||
set(ConfPaths.MOVING_RUNFLY_TRACKER_CHECK, true);
|
||||
set(ConfPaths.MOVING_RUNFLY_TRACKER_MAXTIME, 6000);
|
||||
|
||||
set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWALWAYS, false);
|
||||
set(ConfPaths.MOVING_RUNFLY_FLYING_ALLOWINCREATIVE, true);
|
||||
set(ConfPaths.MOVING_RUNFLY_FLYING_SPEEDLIMITHORIZONTAL, 60);
|
||||
@ -74,8 +77,10 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
|
||||
/*** BLOCKBREAK ***/
|
||||
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_CHECK, true);
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVALSURVIVAL, 45);
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_INTERVALCREATIVE, 145);
|
||||
set(ConfPaths.BLOCKBREAK_FASTBREAK_ACTIONS,
|
||||
"vl>200 cancel vl> 1000 log:bbfastbreak:2:5:cif cancel vl>400 log:bbfastbreak:3:5:cif cmd:kick cancel");
|
||||
"cancel vl>100 log:bbfastbreak:3:5:cif cancel vl>2000 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");
|
||||
@ -103,6 +108,11 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
|
||||
set(ConfPaths.BLOCKPLACE_DIRECTION_PENALTYTIME, 100);
|
||||
set(ConfPaths.BLOCKPLACE_DIRECTION_ACTIONS, "cancel vl>10 log:bpdirection:0:3:if cancel");
|
||||
|
||||
set(ConfPaths.BLOCKPLACE_PROJECTILE_CHECK, true);
|
||||
set(ConfPaths.BLOCKPLACE_PROJECTILE_INTERVAL, 150);
|
||||
set(ConfPaths.BLOCKPLACE_PROJECTILE_ACTIONS,
|
||||
"cancel vl>150 log:bpprojectile:3:5:if cancel vl>1000 log:bpprojectile:3:5:cif cancel vl>4000 log:bpprojectile:3:5:cif cancel cmd:kick");
|
||||
|
||||
/*** CHAT ***/
|
||||
|
||||
set(ConfPaths.CHAT_COLOR_CHECK, true);
|
||||
@ -165,6 +175,8 @@ public class DefaultConfiguration extends NoCheatPlusConfiguration {
|
||||
"[player] failed [check]: tried to interact with a block over distance [reachdistance]. VL [violations]");
|
||||
set(ConfPaths.STRINGS + ".bpdirection",
|
||||
"[player] failed [check]: tried to interact with a block out of line of sight. VL [violations]");
|
||||
set(ConfPaths.STRINGS + ".bpprojectile",
|
||||
"[player] failed [check]: tried to throw items too quicly. VL [violations]");
|
||||
set(ConfPaths.STRINGS + ".color",
|
||||
"[player] failed [check]: Sent colored chat message '[text]'. VL [violations]");
|
||||
set(ConfPaths.STRINGS + ".spam", "[player] failed [check]: Last sent message '[text]'. VL [violations]");
|
||||
|
@ -27,6 +27,8 @@ public class Permissions {
|
||||
public static final String BLOCKPLACE_FASTPLACE = BLOCKPLACE + ".fastplace";
|
||||
public static final String BLOCKPLACE_REACH = BLOCKPLACE + ".reach";
|
||||
public static final String BLOCKPLACE_DIRECTION = BLOCKPLACE + ".direction";
|
||||
public static final String BLOCKPLACE_PROJECTILE = BLOCKPLACE + ".projectile";
|
||||
public static final String BLOCKPLACE_AUTOSIGN = BLOCKPLACE + ".autosign";
|
||||
|
||||
private static final String CHAT = CHECKS + ".chat";
|
||||
public static final String CHAT_SPAM = CHAT + ".spam";
|
||||
|
@ -16,6 +16,7 @@ public class Statistics {
|
||||
BP_FASTPLACE("blockplace.fastplace"),
|
||||
BP_DIRECTION("blockplace.direction"),
|
||||
BP_REACH("blockplace.reach"),
|
||||
BP_PROJECTILE("blockplace.projectile"),
|
||||
CHAT_COLOR("chat.color"),
|
||||
CHAT_SPAM("chat.spam"),
|
||||
FI_DIRECTION("fight.direction"),
|
||||
|
Loading…
Reference in New Issue
Block a user