mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-06-26 06:14:42 +02:00
Review dual wielding.
* Account for off hand in more places. * Use bridge methods to get rid of warnings for now. * Adds utility methods to CheckUtils. * Do not allow left click on off hand (knockback).
This commit is contained in:
parent
241ff08d47
commit
68c4ab2bf2
|
@ -13,7 +13,6 @@ import fr.neatmonster.nocheatplus.actions.ParameterName;
|
|||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
|
||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
|
@ -124,17 +123,7 @@ public class FastConsume extends Check implements Listener{
|
|||
// Reset interaction.
|
||||
if (cancel) {
|
||||
// Fake interaction to prevent violation loops with false positives.
|
||||
ItemStack actualStack = Bridge1_9.getItemInMainHand(player);
|
||||
if (
|
||||
Bridge1_9.hasGetItemInOffHand()
|
||||
&& (actualStack == null || !CheckUtils.isConsumable(actualStack.getType()))
|
||||
) {
|
||||
// Assume this to make sense.
|
||||
actualStack = Bridge1_9.getItemInOffHand(player);
|
||||
if (actualStack == null || !CheckUtils.isConsumable(actualStack.getType())) {
|
||||
actualStack = null;
|
||||
}
|
||||
}
|
||||
final ItemStack actualStack = CheckUtils.getFirstConsumableItemInHand(player);
|
||||
data.instantEatFood = actualStack == null ? null : actualStack.getType();
|
||||
// TODO: Allows some abuse: 1. try instantly eat (cancelled) 2. consume item directly when needed.
|
||||
} else {
|
||||
|
|
|
@ -20,6 +20,7 @@ import fr.neatmonster.nocheatplus.checks.CheckListener;
|
|||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.inventory.Items;
|
||||
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
|
||||
import fr.neatmonster.nocheatplus.permissions.Permissions;
|
||||
import fr.neatmonster.nocheatplus.stats.Counters;
|
||||
|
@ -72,7 +73,8 @@ public class BlockBreakListener extends CheckListener {
|
|||
final Player player = event.getPlayer();
|
||||
|
||||
// Illegal enchantments hotfix check.
|
||||
if (Items.checkIllegalEnchantments(player, player.getItemInHand())) {
|
||||
// TODO: Legacy / encapsulate fully there.
|
||||
if (Items.checkIllegalEnchantmentsAllHands(player)) {
|
||||
event.setCancelled(true);
|
||||
counters.addPrimaryThread(idCancelDIllegalItem, 1);
|
||||
}
|
||||
|
@ -242,7 +244,7 @@ public class BlockBreakListener extends CheckListener {
|
|||
|
||||
final int tick = TickTask.getTick();
|
||||
// Skip if already set to the same block without breaking within one tick difference.
|
||||
final ItemStack stack = player.getItemInHand();
|
||||
final ItemStack stack = Bridge1_9.getItemInMainHand(player);
|
||||
final Material tool = stack == null ? null: stack.getType();
|
||||
if (data.toolChanged(tool)) {
|
||||
// Update.
|
||||
|
|
|
@ -11,6 +11,7 @@ import fr.neatmonster.nocheatplus.checks.Check;
|
|||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.ViolationData;
|
||||
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.permissions.Permissions;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
|
||||
import fr.neatmonster.nocheatplus.utilities.PotionUtil;
|
||||
|
@ -111,7 +112,7 @@ public class FastBreak extends Check {
|
|||
player.sendMessage(data.stats.getStatsStr(true));
|
||||
}
|
||||
// Send info about current break:
|
||||
final ItemStack stack = player.getItemInHand();
|
||||
final ItemStack stack = Bridge1_9.getItemInMainHand(player);
|
||||
final boolean isValidTool = BlockProperties.isValidTool(blockType, stack);
|
||||
final double haste = PotionUtil.getPotionEffectAmplifier(player, PotionEffectType.FAST_DIGGING);
|
||||
String msg = (isInstaBreak.decideOptimistically() ? ("[Insta=" + isInstaBreak + "]") : "[Normal]") + "[" + blockType + "] "+ elapsedTime + "u / " + expectedBreakingTime +"r (" + (isValidTool?"tool":"no-tool") + ")" + (haste == Double.NEGATIVE_INFINITY ? "" : " haste=" + ((int) haste + 1));
|
||||
|
|
|
@ -16,9 +16,11 @@ import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
|||
import fr.neatmonster.nocheatplus.checks.CheckListener;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.combined.CombinedConfig;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
|
||||
import fr.neatmonster.nocheatplus.stats.Counters;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockProperties;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
|
||||
/**
|
||||
* Central location to listen to events that are relevant for the block interact checks.
|
||||
|
@ -83,7 +85,7 @@ public class BlockInteractListener extends CheckListener {
|
|||
case LEFT_CLICK_BLOCK:
|
||||
break;
|
||||
case RIGHT_CLICK_BLOCK:
|
||||
final ItemStack stack = player.getItemInHand();
|
||||
final ItemStack stack = Bridge1_9.getUsedItem(player, event);
|
||||
if (stack != null && stack.getType() == Material.ENDER_PEARL) {
|
||||
if (!BlockProperties.isPassable(block.getType())) {
|
||||
final CombinedConfig ccc = CombinedConfig.getConfig(player);
|
||||
|
@ -135,15 +137,20 @@ public class BlockInteractListener extends CheckListener {
|
|||
// Just prevent using the block.
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
} else {
|
||||
final Result previousUseItem = event.useItemInHand();
|
||||
event.setCancelled(true);
|
||||
event.setUseInteractedBlock(Result.DENY);
|
||||
final ItemStack stack = player.getItemInHand();
|
||||
final Material mat = stack == null ? Material.AIR : stack.getType();
|
||||
if (!preventUseItem && (mat.isEdible() || mat == Material.POTION)) {
|
||||
if (
|
||||
previousUseItem == Result.DENY || preventUseItem
|
||||
// Allow consumption still.
|
||||
|| !CheckUtils.isConsumable(Bridge1_9.getUsedItem(player, event))
|
||||
) {
|
||||
event.setUseItemInHand(Result.DENY);
|
||||
}
|
||||
else {
|
||||
// Consumable and not prevented otherwise.
|
||||
// TODO: Ender pearl?
|
||||
event.setUseItemInHand(Result.ALLOW);
|
||||
} else {
|
||||
event.setUseItemInHand(Result.DENY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public class BlockPlaceListener extends CheckListener {
|
|||
// TODO: Revise material use (not block.get... ?)
|
||||
//final Material mat = block.getType();
|
||||
final Player player = event.getPlayer();
|
||||
final Material placedMat = hasReplacedState ? event.getBlockPlaced().getType() : player.getItemInHand().getType(); // Safety first.
|
||||
final Material placedMat = hasReplacedState ? event.getBlockPlaced().getType() : Bridge1_9.getItemInMainHand(player).getType(); // Safety first.
|
||||
boolean cancelled = false;
|
||||
|
||||
final BlockPlaceData data = BlockPlaceData.getData(player);
|
||||
|
@ -239,7 +239,7 @@ public class BlockPlaceListener extends CheckListener {
|
|||
}
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
final ItemStack stack = player.getItemInHand();
|
||||
final ItemStack stack = Bridge1_9.getUsedItem(player, event);
|
||||
if (stack == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -121,10 +121,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
// Hotfix attempt for enchanted books.
|
||||
// TODO: maybe a generalized version for the future...
|
||||
// Illegal enchantments hotfix check.
|
||||
if (Items.checkIllegalEnchantments(player, Bridge1_9.getItemInMainHand(player))) {
|
||||
return true;
|
||||
}
|
||||
if (Bridge1_9.hasGetItemInOffHand() && Items.checkIllegalEnchantments(player, Bridge1_9.getItemInOffHand(player))) {
|
||||
if (Items.checkIllegalEnchantmentsAllHands(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -616,19 +613,12 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
* @return
|
||||
*/
|
||||
private double getKnockBackLevel(final Player player) {
|
||||
double level = 0.0;
|
||||
double level = 1.0; // 1.0 is the minimum knock-back value.
|
||||
// TODO: Get the RELEVANT item (...).
|
||||
ItemStack stack = Bridge1_9.getItemInMainHand(player);
|
||||
final ItemStack stack = Bridge1_9.getItemInMainHand(player);
|
||||
if (!BlockProperties.isAir(stack)) {
|
||||
level = (double) stack.getEnchantmentLevel(Enchantment.KNOCKBACK);
|
||||
}
|
||||
if (Bridge1_9.hasGetItemInOffHand()) {
|
||||
stack = Bridge1_9.getItemInOffHand(player);
|
||||
if (!BlockProperties.isAir(stack)) {
|
||||
level = Math.max(level, (double) stack.getEnchantmentLevel(Enchantment.KNOCKBACK));
|
||||
}
|
||||
}
|
||||
level += 1.0; // 1.0 is the minimum knock-back value.
|
||||
if (player.isSprinting()) {
|
||||
// TODO: Lost sprint?
|
||||
level += 1.0;
|
||||
|
|
|
@ -34,6 +34,7 @@ import fr.neatmonster.nocheatplus.checks.CheckListener;
|
|||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.combined.Combined;
|
||||
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
|
||||
import fr.neatmonster.nocheatplus.components.JoinLeaveListener;
|
||||
import fr.neatmonster.nocheatplus.stats.Counters;
|
||||
|
@ -356,7 +357,7 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen
|
|||
return;
|
||||
}
|
||||
// TODO: Activate mob-egg check only for specific server versions.
|
||||
final ItemStack stack = player.getItemInHand();
|
||||
final ItemStack stack = Bridge1_9.getUsedItem(player, event);
|
||||
Entity entity = event.getRightClicked();
|
||||
if (stack != null && stack.getType() == Material.MONSTER_EGG
|
||||
&& (entity == null || entity instanceof LivingEntity || entity instanceof ComplexEntityPart)
|
||||
|
|
|
@ -10,24 +10,47 @@ import org.bukkit.inventory.ItemStack;
|
|||
|
||||
import fr.neatmonster.nocheatplus.checks.Check;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
|
||||
public class Items extends Check{
|
||||
|
||||
|
||||
private static Items instance = null;
|
||||
|
||||
public Items() {
|
||||
super(CheckType.INVENTORY_ITEMS);
|
||||
instance = this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks for illegal enchantments (legacy). Removes enchantments from
|
||||
* WRITTEN_BOOK. Check both main and off hand.
|
||||
*
|
||||
* @param player
|
||||
* @return True if the check is failed.
|
||||
*/
|
||||
public static final boolean checkIllegalEnchantmentsAllHands(final Player player) {
|
||||
boolean result = false;
|
||||
if (checkIllegalEnchantments(player, Bridge1_9.getItemInMainHand(player))) {
|
||||
result = true;
|
||||
}
|
||||
if (Bridge1_9.hasGetItemInOffHand() && checkIllegalEnchantments(player, Bridge1_9.getItemInOffHand(player))) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for illegal enchantments (legacy). Removes enchantments from
|
||||
* WRITTEN_BOOK.
|
||||
*
|
||||
* @param player
|
||||
* @param stack
|
||||
* @return True if the check is failed.
|
||||
*/
|
||||
public static final boolean checkIllegalEnchantments(final Player player, final ItemStack stack){
|
||||
if (stack == null) return false;
|
||||
if (stack == null) {
|
||||
return false;
|
||||
}
|
||||
final Material type = stack.getType();
|
||||
// Fastest checks first.
|
||||
// TODO: Make stuff configurable.
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.lang.reflect.Method;
|
|||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
@ -144,4 +146,52 @@ public class Bridge1_9 {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item that was used with this event, assume clicking left or right rather (not feet etc.).
|
||||
* @param player
|
||||
* @param event
|
||||
*/
|
||||
public static ItemStack getUsedItem(final Player player, final PlayerInteractEvent event) {
|
||||
if (!hasGetItemInOffHand()) { // Optimistic check.
|
||||
return getItemInMainHand(player);
|
||||
}
|
||||
else {
|
||||
switch (event.getHand()) {
|
||||
case HAND: {
|
||||
return getItemInMainHand(player);
|
||||
}
|
||||
case OFF_HAND: {
|
||||
return getItemInOffHand(player);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item that was used with this event, assume right click (not feet etc.).
|
||||
* @param player
|
||||
* @param event
|
||||
*/
|
||||
public static ItemStack getUsedItem(final Player player, final PlayerInteractEntityEvent event) {
|
||||
if (!hasGetItemInOffHand()) { // Optimistic check.
|
||||
return getItemInMainHand(player);
|
||||
}
|
||||
else {
|
||||
switch (event.getHand()) {
|
||||
case HAND: {
|
||||
return getItemInMainHand(player);
|
||||
}
|
||||
case OFF_HAND: {
|
||||
return getItemInOffHand(player);
|
||||
}
|
||||
default: {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.bukkit.inventory.ItemStack;
|
|||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup;
|
||||
import fr.neatmonster.nocheatplus.compat.blocks.init.vanilla.VanillaBlocksFactory;
|
||||
|
@ -263,33 +264,33 @@ public class BlockProperties {
|
|||
private static BlockProps defaultBlockProps = instantType;
|
||||
|
||||
protected static final Material[] instantMat = new Material[]{
|
||||
// Named in wiki.
|
||||
Material.CROPS,
|
||||
Material.TRIPWIRE_HOOK, Material.TRIPWIRE,
|
||||
Material.TORCH,
|
||||
Material.TNT,
|
||||
Material.SUGAR_CANE_BLOCK,
|
||||
Material.SAPLING,
|
||||
Material.RED_ROSE, Material.YELLOW_FLOWER,
|
||||
Material.REDSTONE_WIRE,
|
||||
Material.REDSTONE_TORCH_ON, Material.REDSTONE_TORCH_OFF,
|
||||
Material.DIODE_BLOCK_ON, Material.DIODE_BLOCK_OFF,
|
||||
Material.PUMPKIN_STEM,
|
||||
Material.NETHER_WARTS,
|
||||
Material.BROWN_MUSHROOM, Material.RED_MUSHROOM,
|
||||
Material.MELON_STEM,
|
||||
Material.WATER_LILY,
|
||||
Material.LONG_GRASS,
|
||||
Material.FIRE,
|
||||
Material.DEAD_BUSH,
|
||||
//
|
||||
Material.CROPS,
|
||||
// Named in wiki.
|
||||
Material.CROPS,
|
||||
Material.TRIPWIRE_HOOK, Material.TRIPWIRE,
|
||||
Material.TORCH,
|
||||
Material.TNT,
|
||||
Material.SUGAR_CANE_BLOCK,
|
||||
Material.SAPLING,
|
||||
Material.RED_ROSE, Material.YELLOW_FLOWER,
|
||||
Material.REDSTONE_WIRE,
|
||||
Material.REDSTONE_TORCH_ON, Material.REDSTONE_TORCH_OFF,
|
||||
Material.DIODE_BLOCK_ON, Material.DIODE_BLOCK_OFF,
|
||||
Material.PUMPKIN_STEM,
|
||||
Material.NETHER_WARTS,
|
||||
Material.BROWN_MUSHROOM, Material.RED_MUSHROOM,
|
||||
Material.MELON_STEM,
|
||||
Material.WATER_LILY,
|
||||
Material.LONG_GRASS,
|
||||
Material.FIRE,
|
||||
Material.DEAD_BUSH,
|
||||
//
|
||||
Material.CROPS,
|
||||
|
||||
// 1.4
|
||||
Material.COMMAND,
|
||||
Material.FLOWER_POT,
|
||||
Material.CARROT,
|
||||
Material.POTATO,
|
||||
// 1.4
|
||||
Material.COMMAND,
|
||||
Material.FLOWER_POT,
|
||||
Material.CARROT,
|
||||
Material.POTATO,
|
||||
};
|
||||
|
||||
private static BlockCache blockCache = null;
|
||||
|
@ -983,7 +984,9 @@ public class BlockProperties {
|
|||
* @return
|
||||
*/
|
||||
public static long getBreakingDuration(final int blockId, final Player player) {
|
||||
final long res = getBreakingDuration(blockId, player.getItemInHand(), player.getInventory().getHelmet(), player, player.getLocation(useLoc));
|
||||
final long res = getBreakingDuration(blockId,
|
||||
Bridge1_9.getItemInMainHand(player), player.getInventory().getHelmet(),
|
||||
player, player.getLocation(useLoc));
|
||||
useLoc.setWorld(null);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.bukkit.Bukkit;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
|
@ -19,6 +20,7 @@ import fr.neatmonster.nocheatplus.checks.blockbreak.BlockBreakData;
|
|||
import fr.neatmonster.nocheatplus.checks.combined.CombinedData;
|
||||
import fr.neatmonster.nocheatplus.checks.fight.FightData;
|
||||
import fr.neatmonster.nocheatplus.checks.inventory.InventoryData;
|
||||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.hooks.APIUtils;
|
||||
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
|
||||
import fr.neatmonster.nocheatplus.logging.StaticLog;
|
||||
|
@ -266,14 +268,49 @@ public class CheckUtils {
|
|||
return NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(Random.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the item is consumable, like food, potions, milk bucket.
|
||||
*
|
||||
* @param stack
|
||||
* May be null.
|
||||
* @return
|
||||
*/
|
||||
public static boolean isConsumable(final ItemStack stack) {
|
||||
return stack == null ? false : isConsumable(stack.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the item is consumable, like food, potions, milk bucket.
|
||||
*
|
||||
* @param type
|
||||
* May be null.
|
||||
* @return
|
||||
*/
|
||||
public static boolean isConsumable(final Material type) {
|
||||
return type.isEdible() || type == Material.POTION || type == Material.MILK_BUCKET;
|
||||
return type != null &&
|
||||
(type.isEdible() || type == Material.POTION || type == Material.MILK_BUCKET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first consumable item found, checking main hand first and then
|
||||
* off hand, if available. Concerns food/edible, potions, milk bucket.
|
||||
*
|
||||
* @param player
|
||||
* @return null in case no item is consumable.
|
||||
*/
|
||||
public static ItemStack getFirstConsumableItemInHand(final Player player) {
|
||||
ItemStack actualStack = Bridge1_9.getItemInMainHand(player);
|
||||
if (
|
||||
Bridge1_9.hasGetItemInOffHand()
|
||||
&& (actualStack == null || !CheckUtils.isConsumable(actualStack.getType()))
|
||||
) {
|
||||
// Assume this to make sense.
|
||||
actualStack = Bridge1_9.getItemInOffHand(player);
|
||||
if (actualStack == null || !CheckUtils.isConsumable(actualStack.getType())) {
|
||||
actualStack = null;
|
||||
}
|
||||
}
|
||||
return actualStack;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user