Adjust fast breaking and wrong block check, allow '.' for ncp remove

command.
This commit is contained in:
asofold 2012-09-13 22:48:22 +02:00
parent a34b772f8d
commit 9ec4cfaa15
11 changed files with 113 additions and 63 deletions

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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()), " | "));

View File

@ -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";
/*

View File

@ -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

View File

@ -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;