mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-09-03 19:00:30 +02:00
[Bleeding] Add blockinteract.visible check.
This check performs somewhat heuristic ray-tracing to see if a block interacted with can actually be "seen", in terms of not reaching through fully solid blocks. [Still needs for performance: more refined conditions when to use + interact-speed check].
This commit is contained in:
parent
3f7e2d44f1
commit
48ffb2f09f
|
@ -50,6 +50,7 @@ public enum CheckType {
|
||||||
BLOCKINTERACT(BlockInteractConfig.factory, BlockInteractData.factory, Permissions.BLOCKINTERACT),
|
BLOCKINTERACT(BlockInteractConfig.factory, BlockInteractData.factory, Permissions.BLOCKINTERACT),
|
||||||
BLOCKINTERACT_DIRECTION(BLOCKINTERACT, Permissions.BLOCKINTERACT_DIRECTION),
|
BLOCKINTERACT_DIRECTION(BLOCKINTERACT, Permissions.BLOCKINTERACT_DIRECTION),
|
||||||
BLOCKINTERACT_REACH(BLOCKINTERACT, Permissions.BLOCKINTERACT_REACH),
|
BLOCKINTERACT_REACH(BLOCKINTERACT, Permissions.BLOCKINTERACT_REACH),
|
||||||
|
BLOCKINTERACT_VISIBLE(BLOCKINTERACT, Permissions.BLOCKINTERACT_VISIBLE),
|
||||||
|
|
||||||
BLOCKPLACE(BlockPlaceConfig.factory, BlockPlaceData.factory, Permissions.BLOCKPLACE),
|
BLOCKPLACE(BlockPlaceConfig.factory, BlockPlaceData.factory, Permissions.BLOCKPLACE),
|
||||||
BLOCKPLACE_DIRECTION(BLOCKPLACE, Permissions.BLOCKPLACE_DIRECTION),
|
BLOCKPLACE_DIRECTION(BLOCKPLACE, Permissions.BLOCKPLACE_DIRECTION),
|
||||||
|
|
|
@ -76,6 +76,9 @@ public class BlockInteractConfig extends ACheckConfig {
|
||||||
|
|
||||||
public final boolean reachCheck;
|
public final boolean reachCheck;
|
||||||
public final ActionList reachActions;
|
public final ActionList reachActions;
|
||||||
|
|
||||||
|
public final boolean visibleCheck;
|
||||||
|
public final ActionList visibleActions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new block interact configuration.
|
* Instantiates a new block interact configuration.
|
||||||
|
@ -91,6 +94,9 @@ public class BlockInteractConfig extends ACheckConfig {
|
||||||
|
|
||||||
reachCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_REACH_CHECK);
|
reachCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_REACH_CHECK);
|
||||||
reachActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_REACH_ACTIONS, Permissions.BLOCKINTERACT_REACH);
|
reachActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_REACH_ACTIONS, Permissions.BLOCKINTERACT_REACH);
|
||||||
|
|
||||||
|
visibleCheck = data.getBoolean(ConfPaths.BLOCKINTERACT_VISIBLE_CHECK);
|
||||||
|
visibleActions = data.getOptimizedActionList(ConfPaths.BLOCKINTERACT_VISIBLE_ACTIONS, Permissions.BLOCKINTERACT_VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
@ -103,6 +109,8 @@ public class BlockInteractConfig extends ACheckConfig {
|
||||||
return directionCheck;
|
return directionCheck;
|
||||||
case BLOCKINTERACT_REACH:
|
case BLOCKINTERACT_REACH:
|
||||||
return reachCheck;
|
return reachCheck;
|
||||||
|
case BLOCKINTERACT_VISIBLE:
|
||||||
|
return visibleCheck;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,9 @@ public class BlockInteractData extends ACheckData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Violation levels.
|
// Violation levels.
|
||||||
public double directionVL;
|
public double directionVL = 0;
|
||||||
public double reachVL;
|
public double reachVL = 0;
|
||||||
|
public double visibleVL = 0;
|
||||||
|
|
||||||
// Data of the reach check.
|
// Data of the reach check.
|
||||||
public double reachDistance;
|
public double reachDistance;
|
||||||
|
|
|
@ -2,6 +2,7 @@ package fr.neatmonster.nocheatplus.checks.blockinteract;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Event.Result;
|
import org.bukkit.event.Event.Result;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
@ -42,6 +43,9 @@ public class BlockInteractListener extends CheckListener {
|
||||||
/** The reach check. */
|
/** The reach check. */
|
||||||
private final Reach reach = addCheck(new Reach());
|
private final Reach reach = addCheck(new Reach());
|
||||||
|
|
||||||
|
/** The Visible check. */
|
||||||
|
private final Visible visible = addCheck(new Visible());
|
||||||
|
|
||||||
public BlockInteractListener(){
|
public BlockInteractListener(){
|
||||||
super(CheckType.BLOCKINTERACT);
|
super(CheckType.BLOCKINTERACT);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +89,7 @@ public class BlockInteractListener extends CheckListener {
|
||||||
|
|
||||||
boolean cancelled = false;
|
boolean cancelled = false;
|
||||||
|
|
||||||
|
final BlockFace face = event.getBlockFace();
|
||||||
final Location loc = player.getLocation();
|
final Location loc = player.getLocation();
|
||||||
|
|
||||||
// TODO: fast-interact !
|
// TODO: fast-interact !
|
||||||
|
@ -99,6 +104,11 @@ public class BlockInteractListener extends CheckListener {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ray tracing for freecam use etc.
|
||||||
|
if (!cancelled && visible.isEnabled(player) && visible.check(player, loc, block, face, action, data, cc)){
|
||||||
|
cancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
// If one of the checks requested to cancel the event, do so.
|
// If one of the checks requested to cancel the event, do so.
|
||||||
if (cancelled) {
|
if (cancelled) {
|
||||||
event.setUseInteractedBlock(Result.DENY);
|
event.setUseInteractedBlock(Result.DENY);
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
package fr.neatmonster.nocheatplus.checks.blockinteract;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
|
||||||
|
import fr.neatmonster.nocheatplus.checks.Check;
|
||||||
|
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||||
|
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||||
|
import fr.neatmonster.nocheatplus.permissions.Permissions;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.BlockCache;
|
||||||
|
import fr.neatmonster.nocheatplus.utilities.InteractRayTracing;
|
||||||
|
|
||||||
|
public class Visible extends Check {
|
||||||
|
|
||||||
|
private BlockCache blockCache;
|
||||||
|
|
||||||
|
private final InteractRayTracing rayTracing = new InteractRayTracing(false);
|
||||||
|
|
||||||
|
public Visible() {
|
||||||
|
super(CheckType.BLOCKINTERACT_VISIBLE);
|
||||||
|
blockCache = mcAccess.getBlockCache(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see fr.neatmonster.nocheatplus.checks.Check#setMCAccess(fr.neatmonster.nocheatplus.compat.MCAccess)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setMCAccess(MCAccess mcAccess) {
|
||||||
|
super.setMCAccess(mcAccess);
|
||||||
|
// Renew the BlockCache instance.
|
||||||
|
blockCache = mcAccess.getBlockCache(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean check(final Player player, final Location loc, final Block block, final BlockFace face, final Action action, final BlockInteractData data, final BlockInteractConfig cc) {
|
||||||
|
|
||||||
|
// TODO: Might confine what to check for (left/right, target blocks depending on item in hand, container blocks).
|
||||||
|
|
||||||
|
blockCache.setAccess(loc.getWorld());
|
||||||
|
rayTracing.setBlockCache(blockCache);
|
||||||
|
rayTracing.set(loc.getX(), loc.getY() + player.getEyeHeight(), loc.getZ(), 0.5 + block.getX() + 0.6 * face.getModX(), 0.5 + block.getY() + 0.6 * face.getModY(), 0.5 + block.getZ() + 0.6 * face.getModZ());
|
||||||
|
rayTracing.loop();
|
||||||
|
final boolean collides = rayTracing.collides();
|
||||||
|
blockCache.cleanup();
|
||||||
|
rayTracing.cleanup();
|
||||||
|
|
||||||
|
if (cc.debug && player.hasPermission(Permissions.ADMINISTRATION_DEBUG)){
|
||||||
|
player.sendMessage("Interact: " + (action == Action.RIGHT_CLICK_BLOCK ? "right" : "left") + " collide=" + rayTracing.collides());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions ?
|
||||||
|
boolean cancel = false;
|
||||||
|
if (collides){
|
||||||
|
data.visibleVL += 1;
|
||||||
|
if (executeActions(player, data.visibleVL, 1, cc.visibleActions)){
|
||||||
|
cancel = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
data.visibleVL *= 0.99;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -141,6 +141,10 @@ public abstract class ConfPaths {
|
||||||
private static final String BLOCKINTERACT_REACH = BLOCKINTERACT + "reach.";
|
private static final String BLOCKINTERACT_REACH = BLOCKINTERACT + "reach.";
|
||||||
public static final String BLOCKINTERACT_REACH_CHECK = BLOCKINTERACT_REACH + "active";
|
public static final String BLOCKINTERACT_REACH_CHECK = BLOCKINTERACT_REACH + "active";
|
||||||
public static final String BLOCKINTERACT_REACH_ACTIONS = BLOCKINTERACT_REACH + "actions";
|
public static final String BLOCKINTERACT_REACH_ACTIONS = BLOCKINTERACT_REACH + "actions";
|
||||||
|
|
||||||
|
private static final String BLOCKINTERACT_VISIBLE = BLOCKINTERACT + "visible.";
|
||||||
|
public static final String BLOCKINTERACT_VISIBLE_CHECK = BLOCKINTERACT_VISIBLE + "active";
|
||||||
|
public static final String BLOCKINTERACT_VISIBLE_ACTIONS = BLOCKINTERACT_VISIBLE + "actions";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 888 88b, 888 888 888 88e 888
|
* 888 88b, 888 888 888 88e 888
|
||||||
|
|
|
@ -123,7 +123,10 @@ public class DefaultConfig extends ConfigFile {
|
||||||
|
|
||||||
set(ConfPaths.BLOCKINTERACT_REACH_CHECK, true);
|
set(ConfPaths.BLOCKINTERACT_REACH_CHECK, true);
|
||||||
set(ConfPaths.BLOCKINTERACT_REACH_ACTIONS, "cancel vl>5 log:breach:0:2:if cancel");
|
set(ConfPaths.BLOCKINTERACT_REACH_ACTIONS, "cancel vl>5 log:breach:0:2:if cancel");
|
||||||
|
|
||||||
|
set(ConfPaths.BLOCKINTERACT_VISIBLE_CHECK, true);
|
||||||
|
set(ConfPaths.BLOCKINTERACT_VISIBLE_ACTIONS, "cancel vl>5 log:bvisible:0:2:if cancel");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 888 88b, 888 888 888 88e 888
|
* 888 88b, 888 888 888 88e 888
|
||||||
* 888 88P' 888 e88 88e e88'888 888 ee 888 888D 888 ,"Y88b e88'888 ,e e,
|
* 888 88P' 888 e88 88e e88'888 888 ee 888 888D 888 ,"Y88b e88'888 ,e e,
|
||||||
|
@ -425,9 +428,9 @@ public class DefaultConfig extends ConfigFile {
|
||||||
set(ConfPaths.STRINGS + ".bdirection", start + "tried to interact with a block out of his line of sight" + end);
|
set(ConfPaths.STRINGS + ".bdirection", start + "tried to interact with a block out of his line of sight" + end);
|
||||||
set(ConfPaths.STRINGS + ".bedleave", start + "sends bed leave packets (was not in bed)" + end);
|
set(ConfPaths.STRINGS + ".bedleave", start + "sends bed leave packets (was not in bed)" + end);
|
||||||
set(ConfPaths.STRINGS + ".bpspeed", start + "tried to throw projectiles too quickly" + end);
|
set(ConfPaths.STRINGS + ".bpspeed", start + "tried to throw projectiles too quickly" + end);
|
||||||
set(ConfPaths.STRINGS + ".breach", start
|
set(ConfPaths.STRINGS + ".breach", start + "exceeds block-interact distance ([reachdistance])" + end);
|
||||||
+ "tried to interact with a block over distance [reachdistance] block(s)" + end);
|
|
||||||
set(ConfPaths.STRINGS + ".bwrong", start + "broke another block than clicked" + end);
|
set(ConfPaths.STRINGS + ".bwrong", start + "broke another block than clicked" + end);
|
||||||
|
set(ConfPaths.STRINGS + ".bvisible", start + "interacts with a block out of sight" + end);
|
||||||
set(ConfPaths.STRINGS + ".captcha", "[player] failed captcha repeatedly" + end);
|
set(ConfPaths.STRINGS + ".captcha", "[player] failed captcha repeatedly" + end);
|
||||||
set(ConfPaths.STRINGS + ".color", start + "sent colored chat message" + end);
|
set(ConfPaths.STRINGS + ".color", start + "sent colored chat message" + end);
|
||||||
set(ConfPaths.STRINGS + ".commands", start + "issued too many commands" + end);
|
set(ConfPaths.STRINGS + ".commands", start + "issued too many commands" + end);
|
||||||
|
|
|
@ -83,6 +83,7 @@ public class Permissions {
|
||||||
public static final String BLOCKINTERACT = CHECKS + ".blockinteract";
|
public static final String BLOCKINTERACT = CHECKS + ".blockinteract";
|
||||||
public static final String BLOCKINTERACT_DIRECTION = BLOCKINTERACT + ".direction";
|
public static final String BLOCKINTERACT_DIRECTION = BLOCKINTERACT + ".direction";
|
||||||
public static final String BLOCKINTERACT_REACH = BLOCKINTERACT + ".reach";
|
public static final String BLOCKINTERACT_REACH = BLOCKINTERACT + ".reach";
|
||||||
|
public static final String BLOCKINTERACT_VISIBLE = BLOCKINTERACT + ".visible";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 888 88b, 888 888 888 88e 888
|
* 888 88b, 888 888 888 88e 888
|
||||||
|
|
|
@ -42,6 +42,8 @@ public class CheckUtils {
|
||||||
*/
|
*/
|
||||||
public static double directionCheck(final Player player, final double targetX, final double targetY, final double targetZ, final double targetWidth, final double targetHeight, final double precision)
|
public static double directionCheck(final Player player, final double targetX, final double targetY, final double targetZ, final double targetWidth, final double targetHeight, final double precision)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO: optimize !
|
||||||
|
|
||||||
// Get the eye location of the player.
|
// Get the eye location of the player.
|
||||||
final Location eyes = player.getEyeLocation();
|
final Location eyes = player.getEyeLocation();
|
||||||
|
|
|
@ -103,6 +103,8 @@ permissions:
|
||||||
description: Allow the player to bypass to Direction check.
|
description: Allow the player to bypass to Direction check.
|
||||||
nocheatplus.checks.blockinteract.reach:
|
nocheatplus.checks.blockinteract.reach:
|
||||||
description: Allow the player to bypass the Reach check.
|
description: Allow the player to bypass the Reach check.
|
||||||
|
nocheatplus.checks.blockinteract.visible:
|
||||||
|
description: Allow the player to bypass the Visible check.
|
||||||
nocheatplus.checks.blockplace:
|
nocheatplus.checks.blockplace:
|
||||||
description: Allow the player to bypass all BlockPlace checks.
|
description: Allow the player to bypass all BlockPlace checks.
|
||||||
children:
|
children:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user