From 1f83a5ac9fc398db2679cafa22a53f9bb8c81de1 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 23 May 2021 22:32:42 -0400 Subject: [PATCH] Respect tool tier requirement for block breaking (#1837) --- connector/pom.xml | 1 + .../network/session/cache/TagCache.java | 24 ++++++++++++ .../geysermc/connector/utils/BlockUtils.java | 39 ++++++++++++++++--- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 6529dbcd8..9ada540ef 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -305,6 +305,7 @@ String GIT_VERSION = ".*" + String GIT_VERSION = "git-${git.branch}-${git.commit.id.abbrev}" diff --git a/connector/src/main/java/org/geysermc/connector/network/session/cache/TagCache.java b/connector/src/main/java/org/geysermc/connector/network/session/cache/TagCache.java index a417a207f..b1427a864 100644 --- a/connector/src/main/java/org/geysermc/connector/network/session/cache/TagCache.java +++ b/connector/src/main/java/org/geysermc/connector/network/session/cache/TagCache.java @@ -47,6 +47,10 @@ public class TagCache { private IntList pickaxeEffective; private IntList shovelEffective; + private IntList requiresStoneTool; + private IntList requiresIronTool; + private IntList requiresDiamondTool; + /* Items */ private IntList flowers; private IntList foxFood; @@ -67,6 +71,10 @@ public class TagCache { this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe")); this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel")); + this.requiresStoneTool = IntList.of(blockTags.get("minecraft:needs_stone_tool")); + this.requiresIronTool = IntList.of(blockTags.get("minecraft:needs_iron_tool")); + this.requiresDiamondTool = IntList.of(blockTags.get("minecraft:needs_diamond_tool")); + Map itemTags = packet.getTags().get("minecraft:item"); this.flowers = IntList.of(itemTags.get("minecraft:flowers")); this.foxFood = IntList.of(itemTags.get("minecraft:fox_food")); @@ -82,6 +90,10 @@ public class TagCache { this.pickaxeEffective = IntLists.emptyList(); this.shovelEffective = IntLists.emptyList(); + this.requiresStoneTool = IntLists.emptyList(); + this.requiresIronTool = IntLists.emptyList(); + this.requiresDiamondTool = IntLists.emptyList(); + this.flowers = IntLists.emptyList(); this.foxFood = IntLists.emptyList(); this.piglinLoved = IntLists.emptyList(); @@ -119,4 +131,16 @@ public class TagCache { int javaBlockId = blockMapping.getJavaBlockId(); return leaves.contains(javaBlockId) || wool.contains(javaBlockId); } + + public boolean requiresStoneTool(BlockMapping blockMapping) { + return requiresStoneTool.contains(blockMapping.getJavaBlockId()); + } + + public boolean requiresIronTool(BlockMapping blockMapping) { + return requiresIronTool.contains(blockMapping.getJavaBlockId()); + } + + public boolean requiresDiamondTool(BlockMapping blockMapping) { + return requiresDiamondTool.contains(blockMapping.getJavaBlockId()); + } } diff --git a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java index 109aa1564..4dc87d5d8 100644 --- a/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java +++ b/connector/src/main/java/org/geysermc/connector/utils/BlockUtils.java @@ -83,11 +83,36 @@ public class BlockUtils { } } - //http://minecraft.gamepedia.com/Breaking - private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool, + private static boolean canToolTierBreakBlock(GeyserSession session, BlockMapping blockMapping, String toolTier) { + if (toolTier.equals("netherite") || toolTier.equals("diamond")) { + // As of 1.17, these tiers can mine everything that is mineable + return true; + } + + switch (toolTier) { + // Use intentional fall-throughs to check each tier with this block + default: + if (session.getTagCache().requiresStoneTool(blockMapping)) { + return false; + } + case "stone": + if (session.getTagCache().requiresIronTool(blockMapping)) { + return false; + } + case "iron": + if (session.getTagCache().requiresDiamondTool(blockMapping)) { + return false; + } + } + + return true; + } + + // https://minecraft.gamepedia.com/Breaking + private static double calculateBreakTime(double blockHardness, String toolTier, boolean canHarvestWithHand, boolean correctTool, boolean canTierMineBlock, String toolType, boolean isShearsEffective, int toolEfficiencyLevel, int hasteLevel, int miningFatigueLevel, boolean insideOfWaterWithoutAquaAffinity, boolean outOfWaterButNotOnGround, boolean insideWaterAndNotOnGround) { - double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness; + double baseTime = (((correctTool && canTierMineBlock) || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness; double speed = 1.0 / baseTime; if (correctTool) { @@ -125,11 +150,13 @@ public class BlockUtils { String toolType = ""; String toolTier = ""; boolean correctTool = false; + boolean toolCanBreak = false; if (item instanceof ToolItemEntry) { ToolItemEntry toolItem = (ToolItemEntry) item; toolType = toolItem.getToolType(); toolTier = toolItem.getToolTier(); correctTool = correctTool(session, blockMapping, toolType); + toolCanBreak = canToolTierBreakBlock(session, blockMapping, toolTier); } int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(nbtData, "minecraft:efficiency"); int hasteLevel = 0; @@ -137,12 +164,12 @@ public class BlockUtils { if (!isSessionPlayer) { // Another entity is currently mining; we have all the information we know - return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective, + return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, false, false, false); } - hasteLevel = session.getEffectCache().getEffectLevel(Effect.FASTER_DIG); + hasteLevel = Math.max(session.getEffectCache().getEffectLevel(Effect.FASTER_DIG), session.getEffectCache().getEffectLevel(Effect.CONDUIT_POWER)); miningFatigueLevel = session.getEffectCache().getEffectLevel(Effect.SLOWER_DIG); boolean isInWater = session.getCollisionManager().isPlayerInWater(); @@ -152,7 +179,7 @@ public class BlockUtils { boolean outOfWaterButNotOnGround = (!isInWater) && (!session.getPlayerEntity().isOnGround()); boolean insideWaterNotOnGround = isInWater && !session.getPlayerEntity().isOnGround(); - return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolType, isShearsEffective, + return calculateBreakTime(blockMapping.getHardness(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective, toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, outOfWaterButNotOnGround, insideWaterNotOnGround); }