mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-19 14:01:20 +01:00
Adjust fast breaking and wrong block check, allow '.' for ncp remove
command.
This commit is contained in:
parent
a34b772f8d
commit
9ec4cfaa15
@ -105,7 +105,8 @@ public class BlockBreakConfig extends ACheckConfig {
|
||||
public final boolean reachCheck;
|
||||
public final ActionList reachActions;
|
||||
|
||||
public final boolean wrongBlockCheck;
|
||||
public final boolean wrongBlockCheck;
|
||||
public final float wrongBLockLevel;
|
||||
public final ActionList wrongBlockActions;
|
||||
|
||||
/**
|
||||
@ -151,6 +152,7 @@ public class BlockBreakConfig extends ACheckConfig {
|
||||
reachActions = data.getActionList(ConfPaths.BLOCKBREAK_REACH_ACTIONS, Permissions.BLOCKBREAK_REACH);
|
||||
|
||||
wrongBlockCheck = data.getBoolean(ConfPaths.BLOCKBREAK_WRONGBLOCK_CHECK);
|
||||
wrongBLockLevel = data.getInt(ConfPaths.BLOCKBREAK_WRONGBLOCK_LEVEL);
|
||||
wrongBlockActions = data.getActionList(ConfPaths.BLOCKBREAK_WRONGBLOCK_ACTIONS, Permissions.BLOCKBREAK_WRONGBLOCK);
|
||||
}
|
||||
|
||||
|
@ -75,9 +75,10 @@ public class BlockBreakData extends ACheckData {
|
||||
public final ActionFrequency wrongBlockVL;
|
||||
|
||||
// Shared data.
|
||||
public int clickedX;
|
||||
public int clickedY;
|
||||
public int clickedZ;
|
||||
public int clickedX;
|
||||
public int clickedY;
|
||||
public int clickedZ;
|
||||
public long wasInstaBreak;
|
||||
|
||||
public final Stats stats;
|
||||
|
||||
@ -85,12 +86,12 @@ public class BlockBreakData extends ACheckData {
|
||||
public final ActionFrequency fastBreakPenalties;
|
||||
public int fastBreakBuffer;
|
||||
public long fastBreakBreakTime = System.currentTimeMillis() - 1000L;
|
||||
/** Old check sets this to the last interact time, new check sets to first interact time for one block. */
|
||||
/** First time interaction with a block. */
|
||||
public long fastBreakfirstDamage = System.currentTimeMillis();
|
||||
|
||||
public final ActionFrequency frequencyBuckets;
|
||||
public int frequencyShortTermCount;
|
||||
public int frequencyShortTermTick;
|
||||
public int frequencyShortTermCount;
|
||||
public int frequencyShortTermTick;
|
||||
|
||||
// Data of the no swing check.
|
||||
public boolean noSwingArmSwung = true;
|
||||
|
@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.checks.blockbreak;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -11,6 +12,8 @@ import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.player.PlayerAnimationEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
|
||||
/*
|
||||
* M#"""""""'M dP dP M#"""""""'M dP
|
||||
* ## mmmm. `M 88 88 ## mmmm. `M 88
|
||||
@ -91,13 +94,13 @@ public class BlockBreakListener implements Listener {
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
// Has the player broken a block that was not damaged before?
|
||||
if (wrongBlock.isEnabled(player) && wrongBlock.check(player, block, cc, data))
|
||||
if (wrongBlock.isEnabled(player) && wrongBlock.check(player, block, cc, data, isInstaBreak))
|
||||
cancelled = true;
|
||||
|
||||
// Has the player broken more blocks per second than allowed?
|
||||
if (!cancelled && frequency.isEnabled(player) && frequency.check(player, cc, data))
|
||||
cancelled = true;
|
||||
|
||||
|
||||
// Has the player broken blocks faster than possible?
|
||||
if (!isInstaBreak && !cancelled && fastBreak.isEnabled(player) && fastBreak.check(player, block, cc, data))
|
||||
cancelled = true;
|
||||
@ -118,15 +121,25 @@ public class BlockBreakListener implements Listener {
|
||||
if (cancelled){
|
||||
event.setCancelled(cancelled);
|
||||
// Reset damage position:
|
||||
data.fastBreakfirstDamage = now;
|
||||
data.clickedX = block.getX();
|
||||
data.clickedY = block.getY();
|
||||
data.clickedZ = block.getZ();
|
||||
}
|
||||
else{
|
||||
// Invalidate last damage position:
|
||||
data.clickedX = Integer.MAX_VALUE;
|
||||
// data.clickedX = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
if (isInstaBreak){
|
||||
if (cc.fastBreakDebug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)) player.sendMessage("[InstaBreak]");
|
||||
data.wasInstaBreak = now;
|
||||
}
|
||||
else
|
||||
data.wasInstaBreak = 0;
|
||||
|
||||
// Adjust data.
|
||||
data.fastBreakBreakTime = now;
|
||||
// data.fastBreakfirstDamage = now;
|
||||
isInstaBreak = false;
|
||||
}
|
||||
|
||||
@ -170,30 +183,43 @@ public class BlockBreakListener implements Listener {
|
||||
* |_| |_|\__,_|\__, |\___|_| |___|_| |_|\__\___|_| \__,_|\___|\__|
|
||||
* |___/
|
||||
*/
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
// The following is to set the "first damage time" for a block.
|
||||
|
||||
// Return if it is not left clicking a block.
|
||||
// (Allows right click to be ignored.)
|
||||
if (event.getAction() != Action.LEFT_CLICK_BLOCK) return;
|
||||
checkBlockDamage(event.getPlayer(), event.getClickedBlock(), event);
|
||||
|
||||
final long now = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
ignoreCancelled = false, priority = EventPriority.MONITOR)
|
||||
public void onBlockDamage(final BlockDamageEvent event) {
|
||||
if (!event.isCancelled() && event.getInstaBreak()) isInstaBreak = true;
|
||||
checkBlockDamage(event.getPlayer(), event.getBlock(), event);
|
||||
}
|
||||
|
||||
private void checkBlockDamage(final Player player, final Block block, final Cancellable event){
|
||||
final long now = System.currentTimeMillis();
|
||||
final BlockBreakData data = BlockBreakData.getData(player);
|
||||
|
||||
if (event.isCancelled()){
|
||||
// Reset the time, to avoid certain kinds of cheating.
|
||||
data.fastBreakfirstDamage = now;
|
||||
data.clickedX = Integer.MAX_VALUE; // Should be enough to reset that one.
|
||||
return;
|
||||
}
|
||||
// if (event.isCancelled()){
|
||||
// // Reset the time, to avoid certain kinds of cheating. => WHICH ?
|
||||
// data.fastBreakfirstDamage = now;
|
||||
// data.clickedX = Integer.MAX_VALUE; // Should be enough to reset that one.
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Do not care about null blocks.
|
||||
final Block block = event.getClickedBlock();
|
||||
if (block == null)
|
||||
return;
|
||||
|
||||
// if (data.clickedX == block.getX() && data.clickedZ == block.getZ() && data.clickedY == block.getY()) return;
|
||||
// Skip if already set to the same block without breaking.
|
||||
if (data.fastBreakBreakTime < data.fastBreakfirstDamage && data.clickedX == block.getX() && data.clickedZ == block.getZ() && data.clickedY == block.getY())
|
||||
return;
|
||||
|
||||
// (Always set, the interact event only fires once: the first time.)
|
||||
// Only record first damage:
|
||||
data.fastBreakfirstDamage = now;
|
||||
// Also set last clicked blocks position.
|
||||
@ -202,10 +228,4 @@ public class BlockBreakListener implements Listener {
|
||||
data.clickedZ = block.getZ();
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onBlockDamage(final BlockDamageEvent event) {
|
||||
if (event.getInstaBreak()) isInstaBreak = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockUtils;
|
||||
|
||||
@ -49,12 +48,14 @@ public class FastBreak extends Check {
|
||||
boolean cancel = false;
|
||||
|
||||
// First, check the game mode of the player and choose the right limit.
|
||||
long breakingTime = Math.round((double) cc.fastBreakModSurvival / 100D * (double) BlockUtils.getBreakingDuration(block.getTypeId(), player));
|
||||
final long breakingTime;
|
||||
if (player.getGameMode() == GameMode.CREATIVE)
|
||||
breakingTime = Math.round((double) cc.fastBreakModCreative / 100D * (double) 95);
|
||||
|
||||
// fastBreakfirstDamage is now first interact on block (!).
|
||||
final long elapsedTime = now - data.fastBreakfirstDamage;
|
||||
// Modifier defaults to 0, the Frequency check is responsible for those.
|
||||
breakingTime = Math.round((double) cc.fastBreakModCreative / 100D * (double) 100);
|
||||
else
|
||||
breakingTime = Math.round((double) cc.fastBreakModSurvival / 100D * (double) BlockUtils.getBreakingDuration(block.getTypeId(), player));
|
||||
// fastBreakfirstDamage is the first interact on block (!).
|
||||
final long elapsedTime = (data.fastBreakBreakTime > data.fastBreakfirstDamage) ? 0 : now - data.fastBreakfirstDamage;
|
||||
|
||||
// Check if the time used time is lower than expected.
|
||||
if (elapsedTime + cc.fastBreakDelay < breakingTime){
|
||||
@ -62,8 +63,6 @@ public class FastBreak extends Check {
|
||||
|
||||
final long missingTime = breakingTime - elapsedTime;
|
||||
|
||||
|
||||
|
||||
// Add as penalty
|
||||
data.fastBreakPenalties.add(now, (float) missingTime);
|
||||
|
||||
@ -74,28 +73,23 @@ public class FastBreak extends Check {
|
||||
cancel = executeActions(player, data.fastBreakVL, missingTime, cc.fastBreakActions);
|
||||
}
|
||||
// else: still within contention limits.
|
||||
|
||||
// System.out.println("violation : " + missingTime);
|
||||
}
|
||||
else{
|
||||
data.fastBreakVL *= 0.9D;
|
||||
}
|
||||
|
||||
if (cc.fastBreakDebug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
|
||||
if (cc.fastBreakDebug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG) && data.stats != null){
|
||||
data.stats.addStats(data.stats.getId(Integer.toString(block.getTypeId())+"u", true), elapsedTime);
|
||||
data.stats.addStats(data.stats.getId(Integer.toString(block.getTypeId())+ "r", true), breakingTime);
|
||||
player.sendMessage(data.stats.getStatsStr(true));
|
||||
}
|
||||
|
||||
|
||||
// (The break time is set in the listener).
|
||||
|
||||
|
||||
// Remember the block breaking time.
|
||||
data.fastBreakBreakTime = now;
|
||||
|
||||
// Combined speed:
|
||||
// TODO: use some value corresponding to allowed block breaking speed !
|
||||
if (cc.improbableFastBreakCheck && Improbable.check(player, 1f, now))
|
||||
cancel = true;
|
||||
// // Combined speed:
|
||||
// // TODO: use some value corresponding to allowed block breaking speed !
|
||||
// if (cc.improbableFastBreakCheck && Improbable.check(player, 1f, now)) // <- the weight should reflect needed duration
|
||||
// cancel = true;
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ public class Frequency extends Check {
|
||||
if (tick - data.frequencyShortTermTick < cc.frequencyShortTermTicks){
|
||||
// Within range, add.
|
||||
data.frequencyShortTermCount ++;
|
||||
System.out.println(data.frequencyShortTermCount);
|
||||
}
|
||||
else{
|
||||
data.frequencyShortTermTick = tick;
|
||||
|
@ -6,6 +6,7 @@ import org.bukkit.entity.Player;
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
|
||||
import fr.neatmonster.nocheatplus.players.Permissions;
|
||||
|
||||
public class WrongBlock extends Check {
|
||||
|
||||
@ -16,23 +17,54 @@ public class WrongBlock extends Check {
|
||||
/**
|
||||
* Check if the player destroys another block than interacted with last.<br>
|
||||
* This does occasionally trigger for players that destroy grass or snow,
|
||||
* probably due to packet delaying issues for insta breaking. very effective against some nuker techniques.
|
||||
* probably due to packet delaying issues for insta breaking.
|
||||
* @param player
|
||||
* @param block
|
||||
* @param data
|
||||
* @param cc
|
||||
* @param isInstaBreak
|
||||
* @return
|
||||
*/
|
||||
public boolean check(final Player player, final Block block, final BlockBreakConfig cc, final BlockBreakData data){
|
||||
public boolean check(final Player player, final Block block, final BlockBreakConfig cc, final BlockBreakData data, final boolean isInstaBreak){
|
||||
|
||||
boolean cancel = false;
|
||||
if (data.clickedX != block.getX() || data.clickedZ != block.getZ() || data.clickedY != block.getY()){
|
||||
final long now = System.currentTimeMillis();
|
||||
data.wrongBlockVL.add(now, 1f);
|
||||
if (executeActions(player, data.wrongBlockVL.getScore(0.9f), 1D, cc.wrongBlockActions))
|
||||
cancel = true;
|
||||
if (Improbable.check(player, 2.0f, now))
|
||||
cancel = true;
|
||||
|
||||
final boolean wrongTime = data.fastBreakfirstDamage < data.fastBreakBreakTime;
|
||||
final int dist = Math.abs(data.clickedX - block.getX()) + Math.abs(data.clickedY - block.getY()) + Math.abs(data.clickedZ - block.getZ());
|
||||
final boolean wrongBlock;
|
||||
final long now = System.currentTimeMillis();
|
||||
if (dist == 0){
|
||||
if (wrongTime){
|
||||
data.fastBreakBreakTime = now;
|
||||
data.fastBreakfirstDamage = now;
|
||||
// Could set to wrong block, but prefer to transform it into a quasi insta break.
|
||||
}
|
||||
wrongBlock = false;
|
||||
}
|
||||
else if (dist == 1){
|
||||
// One might to a concession in case of insta breaking.
|
||||
if (now - data.wasInstaBreak < 60)
|
||||
wrongBlock = false;
|
||||
else
|
||||
wrongBlock = true;
|
||||
}
|
||||
else
|
||||
wrongBlock = true;
|
||||
|
||||
if (wrongBlock){
|
||||
// Manhattan distance.
|
||||
|
||||
if (cc.fastBreakDebug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
|
||||
player.sendMessage("WrongBlock failure with dist: " + dist);
|
||||
}
|
||||
data.wrongBlockVL.add(now, (float) (dist + 1) / 2f);
|
||||
final float score = data.wrongBlockVL.getScore(0.9f);
|
||||
if (score > cc.wrongBLockLevel){
|
||||
if (executeActions(player, score, 1D, cc.wrongBlockActions))
|
||||
cancel = true;
|
||||
if (Improbable.check(player, 2.0f, now))
|
||||
cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
return cancel;
|
||||
|
@ -55,7 +55,6 @@ public class Improbable extends Check {
|
||||
violated = true;
|
||||
}
|
||||
boolean cancel = false;
|
||||
// System.out.println("IMPROBABLE("+player.getName()+"): " + shortTerm + " / " + full + " / " + violation);
|
||||
if (violated){
|
||||
// Execute actions
|
||||
data.improbableVL += violation / 10.0;
|
||||
|
@ -29,7 +29,7 @@ public class RemovePlayerCommand extends NCPCommand {
|
||||
final CheckType checkType;
|
||||
if (args.length == 3){
|
||||
try{
|
||||
checkType = CheckType.valueOf(args[2].toUpperCase().replace('-', '_'));
|
||||
checkType = CheckType.valueOf(args[2].toUpperCase().replace('-', '_').replace('.', '_'));
|
||||
} catch (Exception e){
|
||||
sender.sendMessage(TAG + "Could not interpret: " + args[2]);
|
||||
sender.sendMessage(TAG + "Check type should be one of: " + CheckUtils.join(Arrays.asList(CheckType.values()), " | "));
|
||||
|
@ -101,6 +101,7 @@ public abstract class ConfPaths {
|
||||
|
||||
private static final String BLOCKBREAK_WRONGBLOCK = BLOCKBREAK + "wrongblock.";
|
||||
public static final String BLOCKBREAK_WRONGBLOCK_CHECK = BLOCKBREAK_WRONGBLOCK + "active";
|
||||
public static final String BLOCKBREAK_WRONGBLOCK_LEVEL = BLOCKBREAK_WRONGBLOCK + "level";
|
||||
public static final String BLOCKBREAK_WRONGBLOCK_ACTIONS = BLOCKBREAK_WRONGBLOCK + "actions";
|
||||
|
||||
/*
|
||||
|
@ -87,7 +87,8 @@ public class DefaultConfig extends ConfigFile {
|
||||
set(ConfPaths.BLOCKBREAK_REACH_ACTIONS, "cancel vl>5 log:breach:0:2:if cancel");
|
||||
|
||||
set(ConfPaths.BLOCKBREAK_WRONGBLOCK_CHECK, true);
|
||||
set(ConfPaths.BLOCKBREAK_WRONGBLOCK_ACTIONS, "cancel vl>5 log:bwrong:0:5:if cancel vl>20 log:bwrong:0:5:if cancel cmd:kickwb");
|
||||
set(ConfPaths.BLOCKBREAK_WRONGBLOCK_LEVEL, 10);
|
||||
set(ConfPaths.BLOCKBREAK_WRONGBLOCK_ACTIONS, "cancel vl>10 log:bwrong:0:5:if cancel vl>30 log:bwrong:0:5:if cancel cmd:kickwb");
|
||||
|
||||
/*
|
||||
* 888 88b, 888 888 888 d8 d8
|
||||
|
@ -314,7 +314,7 @@ public class BlockUtils {
|
||||
blocks[mat.getId()] = new BlockProps(woodPickaxe, 0.7f, railsTimes);
|
||||
}
|
||||
blocks[Material.MONSTER_EGGS.getId()] = new BlockProps(noTool, 0.75f, secToMs(1.15));
|
||||
blocks[Material.WOOL.getId()] = new BlockProps(noTool, 0.8f, secToMs(1.2));
|
||||
blocks[Material.WOOL.getId()] = new BlockProps(noTool, 0.8f, secToMs(1.2), 3f);
|
||||
blocks[Material.SANDSTONE.getId()] = sandStoneType;
|
||||
blocks[Material.SANDSTONE_STAIRS.getId()] = sandStoneType;
|
||||
for (Material mat : new Material[]{
|
||||
@ -507,7 +507,7 @@ public class BlockUtils {
|
||||
// return blockId != 0 && net.minecraft.server.Block.byId[blockId].//.c();// d();
|
||||
final PlayerLocation loc = new PlayerLocation();
|
||||
// Bit fat workaround, maybe put the object through from check listener ?
|
||||
loc.set(location, player);
|
||||
loc.set(location, player, 0.3);
|
||||
return loc.isOnGround();
|
||||
}
|
||||
|
||||
@ -618,12 +618,13 @@ public class BlockUtils {
|
||||
if (!isValidTool && efficiency > 0){
|
||||
// Efficiency makes the tool.
|
||||
// (wood, sand, gravel, ice)
|
||||
if (blockId == Material.WOOL.getId()) return true;
|
||||
if (blockProps.hardness <= 2
|
||||
&& (blockProps.tool.toolType == ToolType.AXE
|
||||
|| blockProps.tool.toolType == ToolType.SPADE
|
||||
|| (blockProps.hardness < 0.8 && (blockId != Material.NETHERRACK.getId() && blockId != Material.SNOW.getId() && blockId != Material.SNOW_BLOCK.getId() && blockId != Material.STONE_PLATE.getId())))){
|
||||
// Also roughly.
|
||||
isValidTool = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isValidTool;
|
||||
|
Loading…
Reference in New Issue
Block a user