Extracted rehandleBreaking and fixed unbreaking

This commit is contained in:
Auxilor
2021-08-30 15:54:14 +01:00
parent 9e9d593eb6
commit aa535375f4
4 changed files with 67 additions and 103 deletions

View File

@@ -2,23 +2,15 @@ package com.willfp.ecoenchants.enchantments.ecoenchants.normal;
import com.willfp.eco.core.integrations.anticheat.AnticheatManager;
import com.willfp.eco.core.integrations.antigrief.AntigriefManager;
import com.willfp.eco.util.BlockUtils;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
import com.willfp.ecoenchants.enchantments.util.EnchantmentUtils;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
@@ -53,8 +45,6 @@ public class BlastMining extends EcoEnchant {
return;
}
AnticheatManager.exemptPlayer(player);
Set<Block> toBreak = new HashSet<>();
for (int x = -1; x <= 1; x++) {
@@ -91,39 +81,8 @@ public class BlastMining extends EcoEnchant {
}
}
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta beforeMeta = itemStack.getItemMeta();
assert beforeMeta != null;
boolean hadUnbreak = beforeMeta.isUnbreakable() || player.getGameMode() == GameMode.CREATIVE;
beforeMeta.setUnbreakable(true);
itemStack.setItemMeta(beforeMeta);
int blocks = toBreak.size();
toBreak.forEach((block1 -> {
block1.setMetadata("block-ignore", this.getPlugin().getMetadataValueFactory().create(true));
BlockUtils.breakBlock(player, block1);
block1.removeMetadata("block-ignore", this.getPlugin());
}));
ItemMeta afterMeta = itemStack.getItemMeta();
assert afterMeta != null;
afterMeta.setUnbreakable(hadUnbreak);
itemStack.setItemMeta(afterMeta);
PlayerItemDamageEvent mockEvent = new PlayerItemDamageEvent(player, itemStack, blocks);
Bukkit.getPluginManager().callEvent(mockEvent);
if (!hadUnbreak) {
ItemMeta wayAfterMeta = itemStack.getItemMeta();
assert wayAfterMeta != null;
((Damageable) wayAfterMeta).setDamage(((Damageable) wayAfterMeta).getDamage() + mockEvent.getDamage());
itemStack.setItemMeta(wayAfterMeta);
if (((Damageable) wayAfterMeta).getDamage() >= itemStack.getType().getMaxDurability()) {
PlayerItemBreakEvent breakEvent = new PlayerItemBreakEvent(player, itemStack);
Bukkit.getPluginManager().callEvent(breakEvent);
itemStack.setAmount(0);
}
}
AnticheatManager.exemptPlayer(player);
EnchantmentUtils.rehandleBreaking(player, toBreak, this.getPlugin());
AnticheatManager.unexemptPlayer(player);
}
}

View File

@@ -6,17 +6,11 @@ import com.willfp.eco.util.BlockUtils;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import com.willfp.ecoenchants.enchantments.util.EnchantmentUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -54,47 +48,10 @@ public class Lumberjack extends EcoEnchant {
int limit = level * blocksPerLevel;
Set<Block> treeBlocks = BlockUtils.getVein(block, materials, limit);
treeBlocks.removeIf(block1 -> !AntigriefManager.canBreakBlock(player, block1));
AnticheatManager.exemptPlayer(player);
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta beforeMeta = itemStack.getItemMeta();
assert beforeMeta != null;
boolean hadUnbreak = beforeMeta.isUnbreakable() || player.getGameMode() == GameMode.CREATIVE;
beforeMeta.setUnbreakable(true);
itemStack.setItemMeta(beforeMeta);
int blocks = treeBlocks.size();
for (Block treeBlock : treeBlocks) {
treeBlock.setMetadata("block-ignore", this.getPlugin().getMetadataValueFactory().create(true));
if (!AntigriefManager.canBreakBlock(player, treeBlock)) {
continue;
}
BlockUtils.breakBlock(player, treeBlock);
this.getPlugin().getScheduler().runLater(() -> treeBlock.removeMetadata("block-ignore", this.getPlugin()), 1);
}
ItemMeta afterMeta = itemStack.getItemMeta();
assert afterMeta != null;
afterMeta.setUnbreakable(hadUnbreak);
itemStack.setItemMeta(afterMeta);
PlayerItemDamageEvent mockEvent = new PlayerItemDamageEvent(player, itemStack, blocks);
Bukkit.getPluginManager().callEvent(mockEvent);
if (!hadUnbreak) {
ItemMeta wayAfterMeta = itemStack.getItemMeta();
assert wayAfterMeta != null;
((Damageable) wayAfterMeta).setDamage(((Damageable) wayAfterMeta).getDamage() + mockEvent.getDamage());
itemStack.setItemMeta(wayAfterMeta);
if (((Damageable) wayAfterMeta).getDamage() >= itemStack.getType().getMaxDurability()) {
PlayerItemBreakEvent breakEvent = new PlayerItemBreakEvent(player, itemStack);
Bukkit.getPluginManager().callEvent(breakEvent);
itemStack.setAmount(0);
}
}
EnchantmentUtils.rehandleBreaking(player, treeBlocks, this.getPlugin());
AnticheatManager.unexemptPlayer(player);
}
}

View File

@@ -6,14 +6,13 @@ import com.willfp.eco.util.BlockUtils;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import com.willfp.ecoenchants.enchantments.meta.EnchantmentType;
import com.willfp.ecoenchants.enchantments.util.EnchantmentUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -48,20 +47,10 @@ public class Vein extends EcoEnchant {
int limit = level * blocksPerLevel;
Set<Block> blockSet = BlockUtils.getVein(block, materials, limit);
blockSet.removeIf(block1 -> !AntigriefManager.canBreakBlock(player, block1));
AnticheatManager.exemptPlayer(player);
for (Block veinBlock : blockSet) {
veinBlock.setMetadata("block-ignore", this.getPlugin().getMetadataValueFactory().create(true));
if (!AntigriefManager.canBreakBlock(player, veinBlock)) {
continue;
}
BlockUtils.breakBlock(player, veinBlock);
this.getPlugin().getScheduler().runLater(() -> veinBlock.removeMetadata("block-ignore", this.getPlugin()), 1);
}
EnchantmentUtils.rehandleBreaking(player, blockSet, this.getPlugin());
AnticheatManager.unexemptPlayer(player);
}
}

View File

@@ -1,22 +1,33 @@
package com.willfp.ecoenchants.enchantments.util;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.integrations.placeholder.PlaceholderEntry;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.util.BlockUtils;
import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils;
import com.willfp.ecoenchants.EcoEnchantsPlugin;
import com.willfp.ecoenchants.enchantments.EcoEnchant;
import com.willfp.ecoenchants.enchantments.EcoEnchants;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@UtilityClass
@SuppressWarnings({"unchecked", "deprecation"})
@@ -131,4 +142,52 @@ public class EnchantmentUtils {
} catch (NoSuchFieldException | IllegalAccessException ignored) {
}
}
/**
* Rehandle breaking in a fast way that doesn't call Player#updateInventory.
*
* @param player The player.
* @param toBreak The blocks to break.
* @param plugin Instance of EcoEnchants, required for meta.
*/
public static void rehandleBreaking(@NotNull final Player player,
@NotNull final Set<Block> toBreak,
@NotNull final EcoPlugin plugin) {
ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta beforeMeta = itemStack.getItemMeta();
assert beforeMeta != null;
boolean hadUnbreak = beforeMeta.isUnbreakable() || player.getGameMode() == GameMode.CREATIVE;
beforeMeta.setUnbreakable(true);
itemStack.setItemMeta(beforeMeta);
int blocks = toBreak.size();
for (Block block : toBreak) {
block.setMetadata("block-ignore", plugin.getMetadataValueFactory().create(true));
BlockUtils.breakBlock(player, block);
block.removeMetadata("block-ignore", plugin);
}
ItemMeta afterMeta = itemStack.getItemMeta();
assert afterMeta != null;
afterMeta.setUnbreakable(hadUnbreak);
itemStack.setItemMeta(afterMeta);
PlayerItemDamageEvent mockEvent = new PlayerItemDamageEvent(player, itemStack, blocks);
Bukkit.getPluginManager().callEvent(mockEvent);
int unbLevel = EnchantChecks.getItemLevel(itemStack, Enchantment.DURABILITY);
double cancelChance = (100 / (double) (unbLevel + 1));
if (hadUnbreak || NumberUtils.randFloat(0, 100) > cancelChance) {
return;
}
ItemMeta wayAfterMeta = itemStack.getItemMeta();
assert wayAfterMeta != null;
((Damageable) wayAfterMeta).setDamage(((Damageable) wayAfterMeta).getDamage() + mockEvent.getDamage());
itemStack.setItemMeta(wayAfterMeta);
if (((Damageable) wayAfterMeta).getDamage() >= itemStack.getType().getMaxDurability()) {
PlayerItemBreakEvent breakEvent = new PlayerItemBreakEvent(player, itemStack);
Bukkit.getPluginManager().callEvent(breakEvent);
itemStack.setAmount(0);
}
}
}