From d91b920d1a85b2ec05f0e77275f7619de69ced6a Mon Sep 17 00:00:00 2001 From: SamB440 Date: Wed, 6 Dec 2023 13:54:48 +0000 Subject: [PATCH] Fix incorrect connecting block handling (legacy versions) --- .../blocks/connecting/DynamicConnecting.java | 12 ++++++---- .../blocks/connecting/DynamicFence.java | 5 ++-- .../blocks/connecting/DynamicPane.java | 5 ++-- .../blocks/connecting/DynamicWall.java | 5 ++-- .../collisions/datatypes/CollisionBox.java | 6 +++++ .../datatypes/SimpleCollisionBox.java | 24 +++++++++++++++++++ 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicConnecting.java b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicConnecting.java index 1793d394f9..f41165c017 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicConnecting.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicConnecting.java @@ -1,7 +1,11 @@ package ac.grim.grimac.utils.collisions.blocks.connecting; import ac.grim.grimac.player.GrimPlayer; -import ac.grim.grimac.utils.collisions.datatypes.*; +import ac.grim.grimac.utils.collisions.datatypes.CollisionBox; +import ac.grim.grimac.utils.collisions.datatypes.ComplexCollisionBox; +import ac.grim.grimac.utils.collisions.datatypes.HexCollisionBox; +import ac.grim.grimac.utils.collisions.datatypes.NoCollisionBox; +import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox; import ac.grim.grimac.utils.nmsutil.Materials; import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.manager.server.ServerVersion; @@ -76,7 +80,7 @@ public boolean connectsTo(GrimPlayer player, ClientVersion v, int currX, int cur } else { if (fence == target) return true; - return checkCanConnect(player, targetBlock, target, fence); + return checkCanConnect(player, targetBlock, target, fence, direction); } } @@ -85,7 +89,7 @@ boolean isBlacklisted(StateType m, StateType fence, ClientVersion clientVersion) if (BlockTags.SHULKER_BOXES.contains(m)) return true; if (BlockTags.TRAPDOORS.contains(m)) return true; - return m == StateTypes.CARVED_PUMPKIN || m == StateTypes.JACK_O_LANTERN || m == StateTypes.PUMPKIN || m == StateTypes.MELON || + return m == StateTypes.ENCHANTING_TABLE || m == StateTypes.CARVED_PUMPKIN || m == StateTypes.JACK_O_LANTERN || m == StateTypes.PUMPKIN || m == StateTypes.MELON || m == StateTypes.BEACON || BlockTags.CAULDRONS.contains(m) || m == StateTypes.GLOWSTONE || m == StateTypes.SEA_LANTERN || m == StateTypes.ICE || m == StateTypes.PISTON || m == StateTypes.STICKY_PISTON || m == StateTypes.PISTON_HEAD || (!canConnectToGlassBlock() && BlockTags.GLASS_BLOCKS.contains(m)); @@ -113,7 +117,7 @@ protected int getAABBIndex(boolean north, boolean east, boolean south, boolean w return i; } - public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two) { + public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) { return false; } diff --git a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicFence.java b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicFence.java index 6fa8a36a8d..1543ce9adc 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicFence.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicFence.java @@ -23,7 +23,6 @@ public class DynamicFence extends DynamicConnecting implements CollisionFactory public static SimpleCollisionBox[] LEGACY_BOUNDING_BOXES = new SimpleCollisionBox[] {new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 0.625D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 0.625D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.375D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.375D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.375D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 0.625D), new SimpleCollisionBox(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D)}; - @Override public CollisionBox fetch(GrimPlayer player, ClientVersion version, WrappedBlockState block, int x, int y, int z) { boolean east; @@ -49,10 +48,10 @@ public CollisionBox fetch(GrimPlayer player, ClientVersion version, WrappedBlock } @Override - public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two) { + public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) { if (BlockTags.FENCES.contains(one)) return !(one == StateTypes.NETHER_BRICK_FENCE) && !(two == StateTypes.NETHER_BRICK_FENCE); else - return BlockTags.FENCES.contains(one) || CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isFullBlock(); + return BlockTags.FENCES.contains(one) || CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isSideFullBlock(direction); } } diff --git a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicPane.java b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicPane.java index 04dc0d193b..465bf5db21 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicPane.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicPane.java @@ -82,12 +82,11 @@ public boolean canConnectToGlassBlock() { return true; } - @Override - public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two) { + public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) { if (BlockTags.GLASS_PANES.contains(one) || one == StateTypes.IRON_BARS) return true; else - return CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isFullBlock(); + return CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isSideFullBlock(direction); } } diff --git a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java index bbe09d1d24..097522b253 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/blocks/connecting/DynamicWall.java @@ -14,6 +14,7 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.South; import com.github.retrooper.packetevents.protocol.world.states.enums.West; import com.github.retrooper.packetevents.protocol.world.states.type.StateType; +import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; public class DynamicWall extends DynamicConnecting implements CollisionFactory { public static final CollisionBox[] BOXES = makeShapes(4.0F, 3.0F, 16.0F, 0.0F, 16.0F, false); @@ -181,7 +182,7 @@ public CollisionBox fetch(GrimPlayer player, ClientVersion version, WrappedBlock } @Override - public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two) { - return BlockTags.WALLS.contains(one) || CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isFullBlock(); + public boolean checkCanConnect(GrimPlayer player, WrappedBlockState state, StateType one, StateType two, BlockFace direction) { + return BlockTags.WALLS.contains(one) || CollisionData.getData(one).getMovementCollisionBox(player, player.getClientVersion(), state, 0, 0, 0).isSideFullBlock(direction); } } diff --git a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/CollisionBox.java b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/CollisionBox.java index f9833236e5..8dfa178db3 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/CollisionBox.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/CollisionBox.java @@ -1,5 +1,7 @@ package ac.grim.grimac.utils.collisions.datatypes; +import com.github.retrooper.packetevents.protocol.world.BlockFace; + import java.util.List; public interface CollisionBox { @@ -16,4 +18,8 @@ public interface CollisionBox { boolean isNull(); boolean isFullBlock(); + + default boolean isSideFullBlock(BlockFace axis) { + return isFullBlock(); + } } \ No newline at end of file diff --git a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java index 0bee4a62f4..cdbed4ffaa 100644 --- a/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java +++ b/src/main/java/ac/grim/grimac/utils/collisions/datatypes/SimpleCollisionBox.java @@ -1,6 +1,7 @@ package ac.grim.grimac.utils.collisions.datatypes; import ac.grim.grimac.utils.nmsutil.Ray; +import com.github.retrooper.packetevents.protocol.world.BlockFace; import com.github.retrooper.packetevents.util.Vector3d; import com.github.retrooper.packetevents.util.Vector3i; import org.bukkit.Location; @@ -240,6 +241,29 @@ public boolean isFullBlock() { return isFullBlock; } + @Override + public boolean isSideFullBlock(BlockFace axis) { + if (isFullBlock) { + return true; + } + + // Get the direction of block we are trying to connect to -> towards the block that is trying to connect + final BlockFace faceToSourceConnector = axis.getOppositeFace(); + switch (faceToSourceConnector) { + case EAST: + case WEST: + return this.minX == 0 && this.maxX == 1; + case UP: + case DOWN: + return this.minY == 0 && this.maxY == 1; + case NORTH: + case SOUTH: + return this.minZ == 0 && this.maxZ == 1; + } + + return false; + } + public boolean isFullBlockNoCache() { return minX == 0 && minY == 0 && minZ == 0 && maxX == 1 && maxY == 1 && maxZ == 1; }