From 9a10ff0439c0c9c165bad419f2ac1bd3aee1ea93 Mon Sep 17 00:00:00 2001 From: Dawson <30784509+funkemunky@users.noreply.github.com> Date: Thu, 29 Sep 2022 16:40:51 -0400 Subject: [PATCH] Fixing bouding boxes, now all latency accounted. New Stair bounding box (from Grim) --- .../ac/check/impl/movement/Phase.java | 8 +- .../check/impl/movement/speed/Horizontal.java | 79 ++-- .../impl/movement/velocity/VelocityB.java | 283 +++++++------- .../ac/data/info/BlockInformation.java | 346 +++++++++--------- .../java/dev/brighten/ac/data/obj/CMove.java | 2 +- .../brighten/ac/handler/BBRevealHandler.java | 44 ++- .../ac/handler/block/BlockUpdateHandler.java | 147 +++----- .../ac/handler/block/WrappedBlock.java | 14 + .../ac/packet/handler/ModernHandler.java | 3 +- .../ac/packet/wrapper/PacketConverter.java | 1 + .../ac/packet/wrapper/impl/Processor_18.java | 145 ++------ .../out/WPacketPlayOutBlockChange.java | 1 + .../out/WPacketPlayOutMultiBlockChange.java | 1 + .../dev/brighten/ac/utils/BlockUtils.java | 40 +- .../java/dev/brighten/ac/utils/Helper.java | 9 +- .../java/dev/brighten/ac/utils/Materials.java | 25 +- .../java/dev/brighten/ac/utils/XMaterial.java | 1 - .../dev/brighten/ac/utils/math/IntVector.java | 24 ++ .../brighten/ac/utils/world/BlockData.java | 76 ++-- .../ac/utils/world/blocks/DoorHandler.java | 47 +-- .../ac/utils/world/blocks/DynamicFence.java | 25 +- .../ac/utils/world/blocks/DynamicPane.java | 23 +- .../ac/utils/world/blocks/DynamicRod.java | 5 +- .../ac/utils/world/blocks/DynamicStair.java | 167 +++++++++ .../ac/utils/world/blocks/DynamicWall.java | 19 +- .../world/blocks/PistonBaseCollision.java | 7 +- .../world/blocks/PistonDickCollision.java | 7 +- .../utils/world/blocks/TrapDoorHandler.java | 7 +- .../utils/world/types/CollisionFactory.java | 5 +- .../world/types/DynamicCollisionBox.java | 21 +- .../ac/utils/world/types/HexCollisionBox.java | 12 + .../ac/utils/world/types/RayCollision.java | 2 +- .../brighten/ac/utils/wrapper/Wrapper.java | 2 + .../ac/utils/wrapper/impl/Wrapper_18R3.java | 9 +- .../wrapper/impl/Wrapper_Reflection.java | 5 + 35 files changed, 882 insertions(+), 730 deletions(-) create mode 100644 src/main/java/dev/brighten/ac/handler/block/WrappedBlock.java create mode 100644 src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java create mode 100644 src/main/java/dev/brighten/ac/utils/world/types/HexCollisionBox.java diff --git a/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java b/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java index f1427eb..6702dcd 100644 --- a/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java +++ b/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java @@ -56,9 +56,9 @@ public class Phase extends Check { SimpleCollisionBox toUpdate = new SimpleCollisionBox(player.getMovement().getTo().getLoc(), 0.6,1.8) - .expand(-0.0825), + .expand(-0.0425), playerBox = new SimpleCollisionBox(player.getBukkitPlayer().getLocation(), 0.6, 1.8) - .expand(-0.0825); + .expand(-0.0425); SimpleCollisionBox concatted = Helper.wrap(playerBox, toUpdate); @@ -71,7 +71,7 @@ public class Phase extends Check { for (Block block : newb) { if(!current.contains(block)) { Material type = block.getType(); - if(Materials.checkFlag(type, Materials.SOLID) + if(Materials.checkFlag(type, Materials.COLLIDABLE) && !allowedMaterials.contains(type) && !Materials.checkFlag(type, Materials.STAIRS)) { tags.addTag("INTO_BLOCK"); @@ -99,7 +99,7 @@ public class Phase extends Check { for (Block block : blocks) { Material type = block.getType(); - if(!Materials.checkFlag(type, Materials.SOLID) + if(!Materials.checkFlag(type, Materials.COLLIDABLE) || allowedMaterials.contains(type) || Materials.checkFlag(type, Materials.STAIRS)) continue; diff --git a/src/main/java/dev/brighten/ac/check/impl/movement/speed/Horizontal.java b/src/main/java/dev/brighten/ac/check/impl/movement/speed/Horizontal.java index 4402655..a509ac7 100644 --- a/src/main/java/dev/brighten/ac/check/impl/movement/speed/Horizontal.java +++ b/src/main/java/dev/brighten/ac/check/impl/movement/speed/Horizontal.java @@ -20,7 +20,6 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.Deque; import java.util.List; @CheckData(name = "Horizontal", checkId = "horizontala", type = CheckType.MOVEMENT) @@ -51,6 +50,8 @@ public class Horizontal extends Check { || player.getInfo().getVelocity().isNotPassed(2) || player.getInfo().isGeneralCancel() || player.getBlockInfo().onClimbable + || player.getMovement().getTo().getLoc().toVector() + .distanceSquared(player.getMovement().getFrom().getLoc().toVector()) > 2500 || player.getInfo().lastLiquid.isNotPassed(2)) { motionX = new Vector(player.getMovement().getDeltaX(), player.getMovement().getDeltaY(), player.getMovement().getDeltaZ()); @@ -67,6 +68,7 @@ public class Horizontal extends Check { boolean found = false; double precision = getPrecision(); TagsBuilder tags = null; + for (Iteration it : iterations) { TagsBuilder tagsBuilder = new TagsBuilder(); float forward = it.f, strafe = it.s; @@ -242,9 +244,10 @@ public class Horizontal extends Check { lmotionY = 0; } + double originalX = lmotionX, originalY = lmotionY, originalZ = lmotionZ; + SimpleCollisionBox box = player.getMovement().getFrom().getBox().copy(); - double originalX = lmotionX, originalY = lmotionY, originalZ = lmotionZ; if(it.sneaking && onGround) { double d6; @@ -407,32 +410,23 @@ public class Horizontal extends Check { tagsBuilder.addTag("stepped"); } - if(originalX != lmotionX) { - tagsBuilder.addTag("x-collision"); - } - - if(originalY != lmotionY) { - tagsBuilder.addTag("y-collision"); - } - - if(originalZ != lmotionZ) { - tagsBuilder.addTag("z-collision"); - } - double x = ((box.minX + box.maxX) / 2.0D) - player.getMovement().getFrom().getX(); double y = box.minY - player.getMovement().getFrom().getY(); double z = ((box.minZ + box.maxZ) / 2.0D) - player.getMovement().getFrom().getZ(); if (originalX != lmotionX) { lmotionX = 0.0D; + tagsBuilder.addTag("x-collision"); } if (originalY != lmotionY) { lmotionY = 0.0D; + tagsBuilder.addTag("y-collision"); } if (originalZ != lmotionZ) { lmotionZ = 0.0D; + tagsBuilder.addTag("z-collision"); } double diffX = player.getMovement().getDeltaX() - x, @@ -442,13 +436,13 @@ public class Horizontal extends Check { double deltaAll = delta + (diffY * diffY); double deltaY = Math.abs(diffY); - if (delta < smallDelta) { + if (deltaAll < smallDelta) { smallDelta = deltaAll; smallestDeltaXZ = delta; smallestDeltaY = deltaY; pmotionx = x; - pmotionz = y; - pmotiony = z; + pmotiony = y; + pmotionz = z; tags = tagsBuilder; @@ -465,8 +459,6 @@ public class Horizontal extends Check { .setLastKnownGoodPosition(player .getMovement().getFrom().getLoc() .clone()); - found = true; - break; } } } @@ -479,8 +471,7 @@ public class Horizontal extends Check { final String builtTags = tags == null ? "null" : tags.build(); - if (player.getMovement().getDeltaXZ() > pmotion - && smallestDeltaXZ > (precision) + if (smallestDeltaXZ > (precision) && player.getMovement().getDeltaXZ() > 0.1) { if ((buffer += smallestDeltaXZ > 58E-5 ? 1 : 0.5) > 1) { buffer = Math.min(3.5f, buffer); //Ensuring we don't have a run-away buffer @@ -488,9 +479,10 @@ public class Horizontal extends Check { player.getMovement().getTo().getLoc(), player.getMovement().getDeltaXZ(), builtTags); cancel(); } else debug("bad movement"); + } else if (buffer > 0) buffer -= 0.05f; - if(smallestDeltaY > 1E-10 && !maybeSkippedPos + if(smallestDeltaY > precision && !player.getBlockInfo().onStairs && !player.getBlockInfo().nearSteppableEntity) { double finalSmallestDeltaY = smallestDeltaY; if(++vbuffer > 1) { @@ -501,10 +493,9 @@ public class Horizontal extends Check { } } else if(vbuffer > 0) vbuffer-= 0.05f; - debug("sx=%s sy=%s py=%.5f ldy=%.5f dy=%.5f posY=%.5f sp=%s pm=%.5f dxz=%.5f b=%.1f tags=[%s]", smallestDeltaXZ, smallestDeltaY, - pmotiony, player.getMovement().getLDeltaY(), player.getMovement().getDeltaY(), player.getMovement().getTo().getY(), - player.getInfo().isSprinting(), pmotion, - player.getMovement().getDeltaXZ(), buffer, builtTags); + debug("(%s): py=%.5f dy=%.5f pm=%.5f dxz=%.5f skip=%s b=%.1f vb=%.1f tags=[%s]", + precision, pmotiony, player.getMovement().getDeltaY(), pmotion, + player.getMovement().getDeltaXZ(), maybeSkippedPos, buffer, vbuffer, builtTags); } if(ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_9)) { @@ -528,7 +519,7 @@ public class Horizontal extends Check { if(player.getBlockInfo().onSoulSand) { return 5E-4; } else if(lastSkipPos.isNotPassed(2)) { - return 0.005; + return 0.03; } return 5E-13; } @@ -538,27 +529,23 @@ public class Horizontal extends Check { val underBlockLoc = previousFrom != null ? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc(); val lastUnderBlockLoc = previousFrom != null ? previousFrom : player.getMovement().getFrom().getLoc(); - Deque frictionList = player.getBlockUpdateHandler() - .getPossibleMaterials(new IntVector(MathHelper.floor_double(underBlockLoc.x), - MathHelper.floor_double(underBlockLoc.y - 1), MathHelper.floor_double(underBlockLoc.z))), - lfrictionList = player.getBlockUpdateHandler() - .getPossibleMaterials(new IntVector(MathHelper.floor_double(lastUnderBlockLoc.x), + Material underMaterial = player.getBlockUpdateHandler() + .getBlock(new IntVector(MathHelper.floor_double(underBlockLoc.x), + MathHelper.floor_double(underBlockLoc.y - 1), MathHelper.floor_double(underBlockLoc.z))).getType(), + lastUnderMaterial = player.getBlockUpdateHandler() + .getBlock(new IntVector(MathHelper.floor_double(lastUnderBlockLoc.x), MathHelper.floor_double(lastUnderBlockLoc.y - 1), - MathHelper.floor_double(lastUnderBlockLoc.z))); + MathHelper.floor_double(lastUnderBlockLoc.z))).getType(); for (int f = -1; f < 2; f++) { - for (Material underMaterial : frictionList) { - for (Material lastUnderMaterial : lfrictionList) { - for (int s = -1; s < 2; s++) { - for (boolean sprinting : getSprintIteration(f)) { - for (int fastMath = 0; fastMath <= 2; fastMath++) { - for (boolean attack : TRUE_FALSE) { - for (boolean using : TRUE_FALSE) { - for (boolean sneaking : getSneakingIteration(sprinting)) { - for (boolean jumped : getJumpingIteration(player.getMovement().getFrom().isOnGround())) { - iterations.add(new Iteration(underMaterial, lastUnderMaterial, f, s, - fastMath, sprinting, attack, using, sneaking, jumped)); - } - } + for (int s = -1; s < 2; s++) { + for (boolean sprinting : getSprintIteration(f)) { + for (int fastMath = 0; fastMath <= 2; fastMath++) { + for (boolean attack : TRUE_FALSE) { + for (boolean using : TRUE_FALSE) { + for (boolean sneaking : getSneakingIteration(sprinting)) { + for (boolean jumped : getJumpingIteration(player.getMovement().getFrom().isOnGround())) { + iterations.add(new Iteration(underMaterial, lastUnderMaterial, f, s, + fastMath, sprinting, attack, using, sneaking, jumped)); } } } diff --git a/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java b/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java index 2132e59..16145b6 100644 --- a/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java +++ b/src/main/java/dev/brighten/ac/check/impl/movement/velocity/VelocityB.java @@ -7,19 +7,16 @@ import dev.brighten.ac.check.WAction; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; -import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.KLocation; import dev.brighten.ac.utils.MathHelper; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.timer.Timer; import dev.brighten.ac.utils.timer.impl.TickTimer; +import lombok.val; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.craftbukkit.v1_8_R3.util.CraftMagicNumbers; import org.bukkit.potion.PotionEffectType; -import java.util.Deque; - @CheckData(name = "Velocity (Horizontal)", checkId = "velocityb", type = CheckType.MOVEMENT) public class VelocityB extends Check { private Timer lastVelocity = new TickTimer(); @@ -54,19 +51,14 @@ public class VelocityB extends Check { check: { if (ticks == 0) break check; - Block underBlock = BlockUtils.getBlock((previousFrom != null ? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc()) - .toLocation(player.getBukkitPlayer().getWorld()) - .subtract(0, 1, 0)), - lastUnderBlock = BlockUtils.getBlock((previousFrom != null ? previousFrom : player.getMovement().getFrom().getLoc()) - .toLocation(player.getBukkitPlayer().getWorld()) - .subtract(0, 1, 0)); - if (underBlock == null || lastUnderBlock == null) - break check; + val underBlockLoc = previousFrom != null + ? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc(); - Deque frictionList = player.getBlockUpdateHandler() - .getPossibleMaterials(new IntVector(underBlock.getX(), underBlock.getY(), underBlock.getZ())), - lfrictionList = player.getBlockUpdateHandler() - .getPossibleMaterials(new IntVector(lastUnderBlock.getX(), lastUnderBlock.getY(), lastUnderBlock.getZ())); + Material underMaterial = player.getBlockUpdateHandler() + .getBlock(new IntVector(MathHelper.floor_double(underBlockLoc.x), + MathHelper.floor_double(underBlockLoc.y - 1), + MathHelper.floor_double(underBlockLoc.z))) + .getType(); if (player.getMovement().getMoveTicks() == 0 || player.getInfo().isGeneralCancel() @@ -85,144 +77,142 @@ public class VelocityB extends Check { loop: { for (int f = -1; f < 2; f++) { - for (Material underMaterial : frictionList) { - for (int s = -1; s < 2; s++) { - for (boolean sprinting : TRUE_FALSE) { - for (int fastMath = 0; fastMath <= 2; fastMath++) { - for (boolean attack : TRUE_FALSE) { - for (boolean using : TRUE_FALSE) { - for (boolean sneaking : TRUE_FALSE) { - for (boolean jumped : TRUE_FALSE) { + for (int s = -1; s < 2; s++) { + for (boolean sprinting : TRUE_FALSE) { + for (int fastMath = 0; fastMath <= 2; fastMath++) { + for (boolean attack : TRUE_FALSE) { + for (boolean using : TRUE_FALSE) { + for (boolean sneaking : TRUE_FALSE) { + for (boolean jumped : TRUE_FALSE) { - float forward = f, strafe = s; + float forward = f, strafe = s; - if (sprinting && forward <= 0) { - continue; + if (sprinting && forward <= 0) { + continue; + } + + if (sneaking) { + forward *= 0.3; + strafe *= 0.3; + } + + float friction = CraftMagicNumbers.getBlock(underMaterial).frictionFactor; + + if (using) { + forward *= 0.2; + strafe *= 0.2; + } + + //Multiplying by 0.98 like in client + forward *= 0.9800000190734863F; + strafe *= 0.9800000190734863F; + + double aiMoveSpeed = player.getBukkitPlayer().getWalkSpeed() / 2; + + float drag = 0.91f; + double lmotionX = pvX, + lmotionZ = pvZ; + + //lmotionX *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; + //lmotionZ *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; + + //Running multiplication done after previous prediction + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { + if (Math.abs(lmotionX) < 0.003) + lmotionX = 0; + if (Math.abs(lmotionZ) < 0.003) + lmotionZ = 0; + } else { + if (Math.abs(lmotionX) < 0.005) + lmotionX = 0; + if (Math.abs(lmotionZ) < 0.005) + lmotionZ = 0; + } + + //Less than 0.05 + if (((lmotionX * lmotionX) + (lmotionZ * lmotionZ)) < 0.0025 && player.getMovement().getDeltaXZ() < 0.2) { + break check; + } + // Attack slowdown + if (attack) { + lmotionX *= 0.6; + lmotionZ *= 0.6; + } + + if (sprinting) + aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; + + if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED)) + aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SPEED) + .get() + .getAmplifier() + 1) * (double) 0.20000000298023224D * aiMoveSpeed; + if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW)) + aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SLOW) + .get() + .getAmplifier() + 1) * (double) -0.15000000596046448D * aiMoveSpeed; + + float f5; + if (onGround) { + drag *= friction; + + f5 = (float) (aiMoveSpeed * (0.16277136F / (drag * drag * drag))); + + if (sprinting && jumped) { + float rot = player.getMovement().getTo().getLoc().yaw * 0.017453292F; + lmotionX -= sin(fastMath, rot) * 0.2F; + lmotionZ += cos(fastMath, rot) * 0.2F; } - if (sneaking) { - forward *= 0.3; - strafe *= 0.3; + } else f5 = sprinting ? 0.025999999F : 0.02f; + + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { + double keyedMotion = forward * forward + strafe * strafe; + + if (keyedMotion >= 1.0E-4F) { + keyedMotion = f5 / Math.max(1.0, Math.sqrt(keyedMotion)); + forward *= keyedMotion; + strafe *= keyedMotion; + + final float yawSin = sin(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), + yawCos = cos(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); + + lmotionX += (strafe * yawCos - forward * yawSin); + lmotionZ += (forward * yawCos + strafe * yawSin); } + } else { + float keyedMotion = forward * forward + strafe * strafe; - float friction = CraftMagicNumbers.getBlock(underMaterial).frictionFactor; + if (keyedMotion >= 1.0E-4F) { + keyedMotion = f5 / Math.max(1.0f, MathHelper.sqrt_float(keyedMotion)); + forward *= keyedMotion; + strafe *= keyedMotion; - if (using) { - forward *= 0.2; - strafe *= 0.2; + final float yawSin = sin(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), + yawCos = cos(fastMath, + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); + + lmotionX += (strafe * yawCos - forward * yawSin); + lmotionZ += (forward * yawCos + strafe * yawSin); } + } + double diffX = player.getMovement().getDeltaX() - lmotionX, + diffZ = player.getMovement().getDeltaZ() - lmotionZ; + double delta = (diffX * diffX) + (diffZ * diffZ); - //Multiplying by 0.98 like in client - forward *= 0.9800000190734863F; - strafe *= 0.9800000190734863F; + if (delta < smallestDelta) { + smallestDelta = delta; + pmotionx = lmotionX; + pmotionz = lmotionZ; + this.friction = friction; - double aiMoveSpeed = player.getBukkitPlayer().getWalkSpeed() / 2; + if (delta < 4E-17) { + this.strafe = s * 0.98f; + this.forward = f * 0.98f; - float drag = 0.91f; - double lmotionX = pvX, - lmotionZ = pvZ; - - //lmotionX *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; - //lmotionZ *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; - - //Running multiplication done after previous prediction - if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { - if (Math.abs(lmotionX) < 0.003) - lmotionX = 0; - if (Math.abs(lmotionZ) < 0.003) - lmotionZ = 0; - } else { - if (Math.abs(lmotionX) < 0.005) - lmotionX = 0; - if (Math.abs(lmotionZ) < 0.005) - lmotionZ = 0; - } - - //Less than 0.05 - if (((lmotionX * lmotionX) + (lmotionZ * lmotionZ)) < 0.0025 && player.getMovement().getDeltaXZ() < 0.2) { - break check; - } - // Attack slowdown - if (attack) { - lmotionX *= 0.6; - lmotionZ *= 0.6; - } - - if (sprinting) - aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; - - if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED)) - aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SPEED) - .get() - .getAmplifier() + 1) * (double) 0.20000000298023224D * aiMoveSpeed; - if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW)) - aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SLOW) - .get() - .getAmplifier() + 1) * (double) -0.15000000596046448D * aiMoveSpeed; - - float f5; - if (onGround) { - drag *= friction; - - f5 = (float) (aiMoveSpeed * (0.16277136F / (drag * drag * drag))); - - if (sprinting && jumped) { - float rot = player.getMovement().getTo().getLoc().yaw * 0.017453292F; - lmotionX -= sin(fastMath, rot) * 0.2F; - lmotionZ += cos(fastMath, rot) * 0.2F; - } - - } else f5 = sprinting ? 0.025999999F : 0.02f; - - if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { - double keyedMotion = forward * forward + strafe * strafe; - - if (keyedMotion >= 1.0E-4F) { - keyedMotion = f5 / Math.max(1.0, Math.sqrt(keyedMotion)); - forward *= keyedMotion; - strafe *= keyedMotion; - - final float yawSin = sin(fastMath, - player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), - yawCos = cos(fastMath, - player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); - - lmotionX += (strafe * yawCos - forward * yawSin); - lmotionZ += (forward * yawCos + strafe * yawSin); - } - } else { - float keyedMotion = forward * forward + strafe * strafe; - - if (keyedMotion >= 1.0E-4F) { - keyedMotion = f5 / Math.max(1.0f, MathHelper.sqrt_float(keyedMotion)); - forward *= keyedMotion; - strafe *= keyedMotion; - - final float yawSin = sin(fastMath, - player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), - yawCos = cos(fastMath, - player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); - - lmotionX += (strafe * yawCos - forward * yawSin); - lmotionZ += (forward * yawCos + strafe * yawSin); - } - } - double diffX = player.getMovement().getDeltaX() - lmotionX, - diffZ = player.getMovement().getDeltaZ() - lmotionZ; - double delta = (diffX * diffX) + (diffZ * diffZ); - - if (delta < smallestDelta) { - smallestDelta = delta; - pmotionx = lmotionX; - pmotionz = lmotionZ; - this.friction = friction; - - if (delta < 4E-17) { - this.strafe = s * 0.98f; - this.forward = f * 0.98f; - - break loop; - } + break loop; } } } @@ -232,6 +222,7 @@ public class VelocityB extends Check { } } } + } } @@ -247,10 +238,10 @@ public class VelocityB extends Check { if (++buffer > 10) { flag("p=%.1f%%", ratio); } - } else if (buffer > 0) buffer-= 0.2; + } else if (buffer > 0) buffer -= 0.2; - debug("r=%.4f smallest=%s f=%s lf=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s ", ratio, smallestDelta, frictionList, lfrictionList, pmotion, - player.getMovement().getDeltaXZ(), buffer, forward, strafe, + debug("r=%.4f smallest=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s ", + ratio, smallestDelta, pmotion, player.getMovement().getDeltaXZ(), buffer, forward, strafe, player.getBlockInfo().onSoulSand); pvX = pmotionx * (0.9100000262260437 * (player.getMovement().getFrom().isOnGround() ? friction : 1)); diff --git a/src/main/java/dev/brighten/ac/data/info/BlockInformation.java b/src/main/java/dev/brighten/ac/data/info/BlockInformation.java index 3ec06cd..6e2b1c1 100644 --- a/src/main/java/dev/brighten/ac/data/info/BlockInformation.java +++ b/src/main/java/dev/brighten/ac/data/info/BlockInformation.java @@ -132,202 +132,200 @@ public class BlockInformation { } - final Deque types = - player.getBlockUpdateHandler().getPossibleMaterials(new IntVector(x, y, z)); + final Material type = + player.getBlockUpdateHandler().getBlock(new IntVector(x, y, z)).getType(); BlockUtils.getBlockAsync(new Location(world, x, y, z)).ifPresent(blocks::add); - for (Material type : types) { - if (type != Material.AIR) { + if (type != Material.AIR) { - IntVector vec = new IntVector(x, y, z); - CollisionBox blockBox = BlockData.getData(type) - .getBox(world, vec, player.getPlayerVersion()); + IntVector vec = new IntVector(x, y, z); + CollisionBox blockBox = BlockData.getData(type) + .getBox(player, vec, player.getPlayerVersion()); - // Checking of within boundsForCollision - if(x >= min.getX() && x <= max.getX() && y >= min.getY() && y <= max.getY() && z >= min.getZ() && z <= max.getZ()) { - collisionMaterialCount.compute(type, (key, count) -> { - if(count == null) return 1; + // Checking of within boundsForCollision + if(x >= min.getX() && x <= max.getX() && y >= min.getY() && y <= max.getY() && z >= min.getZ() && z <= max.getZ()) { + collisionMaterialCount.compute(type, (key, count) -> { + if(count == null) return 1; - return count + 1; - }); + return count + 1; + }); + } + + if(blockBox.isCollided(normalBox)) { + if(type.equals(cobweb)) + inWeb = true; + else if(type.equals(scaffolding)) inScaffolding = true; + else if(type.equals(honey)) inHoney = true; + } + + if(type.equals(rosebush)) + roseBush = true; + + if(normalBox.copy().offset(0, 0.6f, 0).isCollided(blockBox)) + blocksAbove = true; + + if(normalBox.copy().expand(1, -0.0001, 1).isIntersected(blockBox)) + blocksNear = true; + + if(normalBox.copy().expand(0.1, 0, 0.1) + .offset(0, 1,0).isCollided(blockBox)) { + synchronized (aboveCollisions) { + blockBox.downCast(aboveCollisions); + } + } + + if(normalBox.copy().expand(0.1, 0, 0.1) + .expandMax(0, -0.4, 0).expandMin(0, -0.55, 0) + .isCollided(blockBox)) { + synchronized (belowCollisions) { + blockBox.downCast(belowCollisions); + } + } + + if(Materials.checkFlag(type, Materials.COLLIDABLE)) { + SimpleCollisionBox groundBox = newBox(0.6, 0.1) + .expandMax(0, -0.5, 0); + + if(Materials.checkFlag(type, Materials.FENCE) + || Materials.checkFlag(type, Materials.WALL)) { + fenceBelow = true; } - if(blockBox.isCollided(normalBox)) { - if(type.equals(cobweb)) - inWeb = true; - else if(type.equals(scaffolding)) inScaffolding = true; - else if(type.equals(honey)) inHoney = true; - } + XMaterial blockMaterial = BlockUtils.getXMaterial(type); - if(type.equals(rosebush)) - roseBush = true; + if(newBox(1.4, 0).expandMin(0, -1, 0) + .isIntersected(blockBox)) + blocksBelow = true; - if(normalBox.copy().offset(0, 0.6f, 0).isCollided(blockBox)) - blocksAbove = true; + if(normalBox.isIntersected(blockBox)) inBlock = true; - if(normalBox.copy().expand(1, -0.0001, 1).isIntersected(blockBox)) - blocksNear = true; + SimpleCollisionBox box = player.getMovement().getTo().getBox().copy(); - if(normalBox.copy().expand(0.1, 0, 0.1) - .offset(0, 1,0).isCollided(blockBox)) { - synchronized (aboveCollisions) { - blockBox.downCast(aboveCollisions); - } - } + box.expand(Math.abs(player.getMovement().getDeltaXZ() / 2) + 0.1, -0.001, + Math.abs(player.getMovement().getDeltaXZ() / 2) + 0.1); + if (blockBox.isCollided(box)) + collidesHorizontally = true; - if(normalBox.copy().expand(0.1, 0, 0.1) - .expandMax(0, -0.4, 0).expandMin(0, -0.55, 0) - .isCollided(blockBox)) { - synchronized (belowCollisions) { - blockBox.downCast(belowCollisions); - } - } + box = player.getMovement().getTo().getBox().copy(); + box.expand(0, 0.1, 0); - if(Materials.checkFlag(type, Materials.SOLID)) { - SimpleCollisionBox groundBox = newBox(0.6, 0.1) - .expandMax(0, -0.5, 0); + if (blockBox.isCollided(box)) + collidesVertically = true; - if(Materials.checkFlag(type, Materials.FENCE) - || Materials.checkFlag(type, Materials.WALL)) { - fenceBelow = true; - } + if(groundBox.copy().expandMin(0, -0.8, 0) + .isIntersected(blockBox)) + player.getInfo().setNearGround(true); - XMaterial blockMaterial = BlockUtils.getXMaterial(type); - - if(newBox(1.4, 0).expandMin(0, -1, 0) - .isIntersected(blockBox)) - blocksBelow = true; - - if(normalBox.isIntersected(blockBox)) inBlock = true; - - SimpleCollisionBox box = player.getMovement().getTo().getBox().copy(); - - box.expand(Math.abs(player.getMovement().getDeltaXZ() / 2) + 0.1, -0.001, - Math.abs(player.getMovement().getDeltaXZ() / 2) + 0.1); - if (blockBox.isCollided(box)) - collidesHorizontally = true; - - box = player.getMovement().getTo().getBox().copy(); - box.expand(0, 0.1, 0); - - if (blockBox.isCollided(box)) - collidesVertically = true; - - if(groundBox.copy().expandMin(0, -0.8, 0) - .isIntersected(blockBox)) - player.getInfo().setNearGround(true); - - if(groundBox.copy().expandMin(0, -0.4, 0).isCollided(blockBox)) { - player.getInfo().setServerGround(true); - - if(blockMaterial != null) - switch (blockMaterial) { - case ICE: - case BLUE_ICE: - case FROSTED_ICE: - case PACKED_ICE: { - if(groundBox.isCollided(blockBox)) - onIce = true; - break; - } - case SOUL_SAND: { - if(groundBox.isCollided(blockBox)) - onSoulSand = true; - break; - } - case SLIME_BLOCK: { - onSlime = true; - break; - } - } - } - if(player.getMovement().getDeltaY() > 0 - && player.getPlayerVersion().isBelow(ProtocolVersion.V1_14) - && Materials.checkFlag(type, Materials.LADDER) - && normalBox.copy().expand(0.2f, 0, 0.2f) - .isCollided(blockBox)) { - onClimbable = true; - } - - if(blockMaterial != null) { - switch (blockMaterial) { - case PISTON: - case PISTON_HEAD: - case MOVING_PISTON: - case STICKY_PISTON: { - if(normalBox.copy().expand(0.5, 0.5, 0.5) - .isCollided(blockBox)) - pistonNear = true; - break; - } - } - } - - if(groundBox.copy().expand(0.5, 0.3, 0.5).isCollided(blockBox)) { - if(Materials.checkFlag(type, Materials.SLABS)) - onSlab = true; - else - if(Materials.checkFlag(type, Materials.STAIRS)) - onStairs = true; - else if(Materials.checkFlag(type, Materials.FENCE) - || Materials.checkFlag(type, Materials.WALL)) { - fenceNear = true; - } else if(blockMaterial != null) - switch(blockMaterial) { - case CAKE: - case BREWING_STAND: - case FLOWER_POT: - case PLAYER_HEAD: - case PLAYER_WALL_HEAD: - case SKELETON_SKULL: - case CREEPER_HEAD: - case DRAGON_HEAD: - case ZOMBIE_HEAD: - case ZOMBIE_WALL_HEAD: - case CREEPER_WALL_HEAD: - case DRAGON_WALL_HEAD: - case WITHER_SKELETON_SKULL: - case LANTERN: - case SKELETON_WALL_SKULL: - case WITHER_SKELETON_WALL_SKULL: - case SNOW: { - miscNear = true; - break; - } - case BLACK_BED: - case BLUE_BED: - case BROWN_BED: - case CYAN_BED: - case GRAY_BED: - case GREEN_BED: - case LIME_BED: - case MAGENTA_BED: - case ORANGE_BED: - case PINK_BED: - case PURPLE_BED: - case RED_BED: - case WHITE_BED: - case YELLOW_BED: - case LIGHT_BLUE_BED: - case LIGHT_GRAY_BED: { - bedNear = true; - break; - } - } - } - } else if(blockBox.isCollided(normalBox)) { - XMaterial blockMaterial = BlockUtils.getXMaterial(type); + if(groundBox.copy().expandMin(0, -0.4, 0).isCollided(blockBox)) { + player.getInfo().setServerGround(true); if(blockMaterial != null) - switch(blockMaterial) { - case END_PORTAL: - case NETHER_PORTAL: { - inPortal = true; + switch (blockMaterial) { + case ICE: + case BLUE_ICE: + case FROSTED_ICE: + case PACKED_ICE: { + if(groundBox.isCollided(blockBox)) + onIce = true; + break; + } + case SOUL_SAND: { + if(groundBox.isCollided(blockBox)) + onSoulSand = true; + break; + } + case SLIME_BLOCK: { + onSlime = true; break; } } } + if(player.getMovement().getDeltaY() > 0 + && player.getPlayerVersion().isBelow(ProtocolVersion.V1_14) + && Materials.checkFlag(type, Materials.LADDER) + && normalBox.copy().expand(0.2f, 0, 0.2f) + .isCollided(blockBox)) { + onClimbable = true; + } + + if(blockMaterial != null) { + switch (blockMaterial) { + case PISTON: + case PISTON_HEAD: + case MOVING_PISTON: + case STICKY_PISTON: { + if(normalBox.copy().expand(0.5, 0.5, 0.5) + .isCollided(blockBox)) + pistonNear = true; + break; + } + } + } + + if(groundBox.copy().expand(0.5, 0.3, 0.5).isCollided(blockBox)) { + if(Materials.checkFlag(type, Materials.SLABS)) + onSlab = true; + else + if(Materials.checkFlag(type, Materials.STAIRS)) + onStairs = true; + else if(Materials.checkFlag(type, Materials.FENCE) + || Materials.checkFlag(type, Materials.WALL)) { + fenceNear = true; + } else if(blockMaterial != null) + switch(blockMaterial) { + case CAKE: + case BREWING_STAND: + case FLOWER_POT: + case PLAYER_HEAD: + case PLAYER_WALL_HEAD: + case SKELETON_SKULL: + case CREEPER_HEAD: + case DRAGON_HEAD: + case ZOMBIE_HEAD: + case ZOMBIE_WALL_HEAD: + case CREEPER_WALL_HEAD: + case DRAGON_WALL_HEAD: + case WITHER_SKELETON_SKULL: + case LANTERN: + case SKELETON_WALL_SKULL: + case WITHER_SKELETON_WALL_SKULL: + case SNOW: { + miscNear = true; + break; + } + case BLACK_BED: + case BLUE_BED: + case BROWN_BED: + case CYAN_BED: + case GRAY_BED: + case GREEN_BED: + case LIME_BED: + case MAGENTA_BED: + case ORANGE_BED: + case PINK_BED: + case PURPLE_BED: + case RED_BED: + case WHITE_BED: + case YELLOW_BED: + case LIGHT_BLUE_BED: + case LIGHT_GRAY_BED: { + bedNear = true; + break; + } + } + } + } else if(blockBox.isCollided(normalBox)) { + XMaterial blockMaterial = BlockUtils.getXMaterial(type); + + if(blockMaterial != null) + switch(blockMaterial) { + case END_PORTAL: + case NETHER_PORTAL: { + inPortal = true; + break; + } + } } } } diff --git a/src/main/java/dev/brighten/ac/data/obj/CMove.java b/src/main/java/dev/brighten/ac/data/obj/CMove.java index 16e541b..faa6337 100644 --- a/src/main/java/dev/brighten/ac/data/obj/CMove.java +++ b/src/main/java/dev/brighten/ac/data/obj/CMove.java @@ -11,7 +11,7 @@ import org.bukkit.World; public class CMove { private KLocation loc = new KLocation(0,0,0,0,0); private World world; - private SimpleCollisionBox box; + private SimpleCollisionBox box = new SimpleCollisionBox(new KLocation(0,0,0,0,0), 0.6f, 1.8f); private boolean onGround; public void setLoc(CMove move) { this.loc = move.getLoc().clone(); diff --git a/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java b/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java index 7c797cf..de00761 100644 --- a/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java +++ b/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java @@ -3,12 +3,11 @@ package dev.brighten.ac.handler; import dev.brighten.ac.Anticheat; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.objects.EnumParticle; -import dev.brighten.ac.utils.Helper; import dev.brighten.ac.utils.ItemBuilder; +import dev.brighten.ac.utils.Materials; import dev.brighten.ac.utils.annotation.Init; import dev.brighten.ac.utils.world.BlockData; import dev.brighten.ac.utils.world.EntityData; -import dev.brighten.ac.utils.world.types.SimpleCollisionBox; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Bukkit; @@ -17,6 +16,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEntityEvent; @@ -43,24 +43,33 @@ public class BBRevealHandler implements Listener { runShowTask(); } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST) public void onInteract(PlayerInteractEvent event) { if(!event.getPlayer().getItemInHand().isSimilar(wand)) return; if(event.getAction() == Action.RIGHT_CLICK_BLOCK) { - if(blocksToShow.contains(event.getClickedBlock())) { - blocksToShow.remove(event.getClickedBlock()); - event.getPlayer().spigot().sendMessage(new ComponentBuilder("No longer showing block.") - .color(ChatColor.RED).create()); + if(Materials.checkFlag(event.getClickedBlock().getType(), Materials.COLLIDABLE)) { + if(blocksToShow.contains(event.getClickedBlock())) { + blocksToShow.remove(event.getClickedBlock()); + event.getPlayer().spigot().sendMessage(new ComponentBuilder("No longer showing block: ") + .color(ChatColor.RED).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) + .create()); + } else { + blocksToShow.add(event.getClickedBlock()); + event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ") + .color(ChatColor.GREEN).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) + .create()); + } } else { - blocksToShow.add(event.getClickedBlock()); - event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block.") - .color(ChatColor.GREEN).create()); + event.getPlayer().spigot().sendMessage(new ComponentBuilder("Block is not collidable!") + .color(ChatColor.RED) + .create()); } + event.setCancelled(true); } } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST) public void onInteract(PlayerInteractEntityEvent event) { if(!event.getPlayer().getItemInHand().isSimilar(wand)) return; @@ -69,11 +78,13 @@ public class BBRevealHandler implements Listener { event.getPlayer().spigot().sendMessage(new ComponentBuilder("No longer showing entity " + event.getRightClicked().getName() + ".") .color(ChatColor.RED).create()); + event.setCancelled(true); } else { entitiesToShow.add(event.getRightClicked()); event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing entity " + event.getRightClicked().getName() + ".") .color(ChatColor.GREEN).create()); + event.setCancelled(true); } } @@ -86,15 +97,10 @@ public class BBRevealHandler implements Listener { blocksToShow.forEach(b -> BlockData.getData(b.getType()).getBox(b, ProtocolVersion.getGameVersion()) .draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0]))); entitiesToShow.forEach(e -> { - SimpleCollisionBox box; - if((box =Helper.getEntityCollision(e)) != null) { - box.draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0])); - } else { - EntityData.getEntityBox(e.getLocation(), e) - .draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0])); - } + EntityData.getEntityBox(e.getLocation(), e) + .draw(EnumParticle.FLAME, Bukkit.getOnlinePlayers().toArray(new Player[0])); }); - }, 3000, 500, TimeUnit.MILLISECONDS); + }, 3000, 250, TimeUnit.MILLISECONDS); } } diff --git a/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java b/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java index 10a535d..d1c768e 100644 --- a/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java +++ b/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java @@ -7,22 +7,21 @@ import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutBlockChange; import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutMultiBlockChange; import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.Materials; -import dev.brighten.ac.utils.Tuple; import dev.brighten.ac.utils.XMaterial; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.world.types.RayCollision; -import dev.brighten.ac.utils.wrapper.Wrapper; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import lombok.RequiredArgsConstructor; -import lombok.val; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; -import java.util.*; +import java.util.Optional; @RequiredArgsConstructor public class BlockUpdateHandler { - private final Map> blockInformation = new Object2ObjectOpenHashMap<>(); + private final Int2ObjectOpenHashMap blockInformation = new Int2ObjectOpenHashMap<>(); private final APlayer player; @@ -32,6 +31,7 @@ public class BlockUpdateHandler { /** * Keep track of block placements since the Bukkit API will be a bit behind + * * @param place */ public void onPlace(WPacketPlayInBlockPlace place) { @@ -40,18 +40,18 @@ public class BlockUpdateHandler { IntVector pos = place.getBlockPos().clone(); // Some dumbass shit I have to do because Minecraft with Lilypads - if(place.getItemStack() != null && BlockUtils.getXMaterial(place.getItemStack().getType()).equals(XMaterial.LILY_PAD)) { + if (place.getItemStack() != null && BlockUtils.getXMaterial(place.getItemStack().getType()).equals(XMaterial.LILY_PAD)) { RayCollision rayCollision = new RayCollision(player.getBukkitPlayer().getEyeLocation().toVector(), player.getBukkitPlayer().getLocation().getDirection()); Block block = rayCollision.getClosestBlockOfType(player.getBukkitPlayer().getWorld(), Materials.LIQUID, 5); - if(block != null) { + if (block != null) { if (Materials.checkFlag(block.getType(), Materials.WATER)) { pos = new IntVector(block.getX(), block.getY() + 1, block.getZ()); } } else return; } // Not an actual block place, just an interact - else if(pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) { + else if (pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) { return; } else { pos.setX(pos.getX() + place.getDirection().getAdjacentX()); @@ -61,49 +61,38 @@ public class BlockUpdateHandler { player.getInfo().getLastPlace().reset(); - Deque possible = getPossibleMaterials(pos); - possible.add(place.getItemStack().getType()); + synchronized (blockInformation) { + blockInformation.put(pos.hashCode(), new WrappedBlock(pos.toLocation(player.getBukkitPlayer().getWorld()), + place.getItemStack().getType(), (byte) 0)); + } } /** * Keep track of block breaking since the Bukkit API will be a bit behind. + * * @param dig */ public void onDig(WPacketPlayInBlockDig dig) { player.getInfo().lastBlockUpdate.reset(); - if(dig.getDigType() == WPacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { - Deque possible = getPossibleMaterials(dig.getBlockPos()); - possible.clear(); - possible.add(Material.AIR); + if (dig.getDigType() == WPacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { + synchronized (blockInformation) { + blockInformation.put(dig.getBlockPos().hashCode(), + new WrappedBlock(dig.getBlockPos().toLocation(player.getBukkitPlayer().getWorld()), + Material.AIR, (byte) 0)); + } } } public void runUpdate(WPacketPlayOutBlockChange packet) { player.getInfo().lastBlockUpdate.reset(); + synchronized (blockInformation) { - Deque blockInfo = blockInformation.compute(packet.getBlockLocation(), (blockLoc, blockI) -> { - if(blockI == null) { - blockI = new LinkedList<>(); - - val optional = BlockUtils - .getBlockAsync(packet.getBlockLocation().toBukkitVector() - .toLocation(player.getBukkitPlayer().getWorld())); - - if(optional.isPresent()) { - Block block = optional.get(); - - blockI.add(block.getType()); - } - } - - return blockI; - }); // Updating block information player.runInstantAction(k -> { - if (!k.isEnd()) { - blockInfo.add(packet.getMaterial()); - } else if (blockInfo.size() > 1) { - blockInfo.removeFirst(); + if (k.isEnd()) { + blockInformation.put(packet.getBlockLocation().hashCode(), + new WrappedBlock(packet.getBlockLocation().toLocation(player.getBukkitPlayer().getWorld()), + packet.getMaterial(), packet.getBlockData())); } }); } @@ -111,70 +100,52 @@ public class BlockUpdateHandler { public void runUpdate(WPacketPlayOutMultiBlockChange packet) { player.getInfo().lastBlockUpdate.reset(); - List, Material>> changes = new ArrayList<>(); - synchronized (blockInformation) { - for (WPacketPlayOutMultiBlockChange.BlockChange change : packet.getChanges()) { - Deque blockInfo = blockInformation.compute(change.getLocation(), (blockLoc, blockI) -> { - if(blockI == null) { - blockI = new LinkedList<>(); - - val optional = BlockUtils - .getBlockAsync(change.getLocation().toBukkitVector() - .toLocation(player.getBukkitPlayer().getWorld())); - - if(optional.isPresent()) { - Block block = optional.get(); - - blockI.add(block.getType()); - } - } - - return blockI; - }); - - changes.add(new Tuple<>(blockInfo, change.getMaterial())); - } - - } player.runInstantAction(k -> { - if(!k.isEnd()) { - for (Tuple, Material> tuple : changes) { - tuple.one.add(tuple.two); - } - } else { - for (Tuple, Material> tuple : changes) { - if(tuple.one.size() > 1) { - tuple.one.removeFirst(); + if (k.isEnd()) { + synchronized (blockInformation) { + for (WPacketPlayOutMultiBlockChange.BlockChange info : packet.getChanges()) { + blockInformation.put(info.getLocation().hashCode(), + new WrappedBlock(info.getLocation().toLocation(player.getBukkitPlayer().getWorld()), + info.getMaterial(), info.getData())); } } } }); } - public Deque getPossibleMaterials(IntVector loc) { + public WrappedBlock getBlock(IntVector loc) { synchronized (blockInformation) { - Deque blockI = blockInformation.get(loc); + final int hashCode = loc.hashCode(); + WrappedBlock block = blockInformation.get(hashCode); - if(blockI == null) { - blockI = new LinkedList<>(); + if (block == null) { + Optional bukkitBlock = BlockUtils.getBlockAsync( + new Location(player.getBukkitPlayer().getWorld(), loc.getX(), loc.getY(), loc.getZ())); - Material type = Wrapper.getInstance().getType(player.getBukkitPlayer().getWorld(), - loc.getX(), loc.getY(), loc.getZ()); - - blockI.add(type); - - blockInformation.put(loc, blockI); - } else if(blockI.size() == 0) { - Material type = Wrapper.getInstance().getType(player.getBukkitPlayer().getWorld(), - loc.getX(), loc.getY(), loc.getZ()); - - blockI.add(type); - - blockInformation.put(loc, blockI); + if (bukkitBlock.isPresent()) { + Location bloc = bukkitBlock.get().getLocation(); + IntVector intVec = new IntVector(bloc.getBlockX(), bloc.getBlockY(), bloc.getBlockZ()); + block = new WrappedBlock(intVec.toLocation(player.getBukkitPlayer().getWorld()), + bukkitBlock.get().getType(), bukkitBlock.get().getData()); + blockInformation.put(hashCode, block); + } } - return blockI; + return block; } } -} + + public WrappedBlock getRelative(IntVector location, int modX, int modY, int modZ) { + return getBlock(location.clone().add(modX, modY, modZ)); + } + + public WrappedBlock getRelative(IntVector location, BlockFace face, int distance) { + return getRelative(location, + face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance); + } + + public WrappedBlock getRelative(IntVector location, BlockFace face) { + return getBlock(location.clone().add(face.getModX(), face.getModY(), face.getModZ())); + } +} \ No newline at end of file diff --git a/src/main/java/dev/brighten/ac/handler/block/WrappedBlock.java b/src/main/java/dev/brighten/ac/handler/block/WrappedBlock.java new file mode 100644 index 0000000..5db987e --- /dev/null +++ b/src/main/java/dev/brighten/ac/handler/block/WrappedBlock.java @@ -0,0 +1,14 @@ +package dev.brighten.ac.handler.block; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.Material; + +@Getter +@AllArgsConstructor +public class WrappedBlock { + private Location location; + private Material type; + private byte data; +} diff --git a/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java b/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java index 77a9f83..d24804c 100644 --- a/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java +++ b/src/main/java/dev/brighten/ac/packet/handler/ModernHandler.java @@ -12,7 +12,6 @@ import dev.brighten.ac.utils.reflections.impl.CraftReflection; import dev.brighten.ac.utils.reflections.impl.MinecraftReflection; import dev.brighten.ac.utils.reflections.types.WrappedClass; import io.netty.channel.*; -import lombok.SneakyThrows; import net.minecraft.server.v1_8_R3.PacketLoginInStart; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -219,7 +218,7 @@ public class ModernHandler extends HandlerAbstract { } } - if(player != null) { + if(player != null && Anticheat.INSTANCE.getPacketProcessor() != null) { try { Object returnedObject = Anticheat.INSTANCE.getPacketProcessor().call(player, msg, type); diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java b/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java index 8c7d8a3..fc4ff66 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/PacketConverter.java @@ -6,6 +6,7 @@ import dev.brighten.ac.packet.wrapper.out.*; public interface PacketConverter { WPacketPlayInFlying processFlying(Object object); + WPacketPlayInUseEntity processUseEntity(Object object); WPacketPlayInAbilities processAbilities(Object object); diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java b/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java index 165e98e..cb0605e 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/impl/Processor_18.java @@ -32,24 +32,21 @@ public class Processor_18 implements PacketConverter { @Override public WPacketPlayInFlying processFlying(Object object) { PacketPlayInFlying flying = (PacketPlayInFlying) object; - WPacketPlayInFlying f = WPacketPlayInFlying.builder().x(flying.a()).y(flying.b()).z(flying.c()).yaw(flying.d()) - .pitch(flying.e()).onGround(flying.f()).moved(flying.g()).looked(flying.h()).build(); - return f; + return WPacketPlayInFlying.builder().x(flying.a()).y(flying.b()).z(flying.c()).yaw(flying.d()) + .pitch(flying.e()).onGround(flying.f()).moved(flying.g()).looked(flying.h()).build(); } - private static WrappedClass classUseEntity = new WrappedClass(PacketPlayInUseEntity.class); - private static WrappedField fieldEntityId = classUseEntity.getFieldByName("a"); + private static final WrappedClass classUseEntity = new WrappedClass(PacketPlayInUseEntity.class); + private static final WrappedField fieldEntityId = classUseEntity.getFieldByName("a"); @Override public WPacketPlayInUseEntity processUseEntity(Object object) { PacketPlayInUseEntity useEntity = (PacketPlayInUseEntity) object; - WPacketPlayInUseEntity ue = WPacketPlayInUseEntity.builder().entityId(fieldEntityId.get(useEntity)) + return WPacketPlayInUseEntity.builder().entityId(fieldEntityId.get(useEntity)) .action(WPacketPlayInUseEntity.EnumEntityUseAction.valueOf(useEntity.a().name())) .vector(useEntity.b() != null ? new Vector(useEntity.b().a, useEntity.b().b, useEntity.b().c) : null) .build(); - - return ue; } private static final WrappedClass classAbilities = new WrappedClass(PacketPlayInAbilities.class), @@ -64,7 +61,7 @@ public class Processor_18 implements PacketConverter { public WPacketPlayInAbilities processAbilities(Object object) { PacketPlayInAbilities abilities = (PacketPlayInAbilities) object; - WPacketPlayInAbilities a = WPacketPlayInAbilities.builder() + return WPacketPlayInAbilities.builder() .capabilities(PlayerCapabilities.builder() .isInvulnerable(abilities.a()) .isFlying(abilities.isFlying()) @@ -74,20 +71,13 @@ public class Processor_18 implements PacketConverter { .walkSpeed(fieldWalkSpeed.get(abilities)) .build()) .build(); - - - - return a; } @Override public WPacketPlayInArmAnimation processAnimation(Object object) { PacketPlayInArmAnimation packet = (PacketPlayInArmAnimation) object; - WPacketPlayInArmAnimation aa = WPacketPlayInArmAnimation.builder().timestamp(packet.timestamp).build(); - - - return aa; + return WPacketPlayInArmAnimation.builder().timestamp(packet.timestamp).build(); } @Override @@ -96,15 +86,11 @@ public class Processor_18 implements PacketConverter { BlockPosition pos = packet.a(); - WPacketPlayInBlockDig bd = WPacketPlayInBlockDig.builder() + return WPacketPlayInBlockDig.builder() .blockPos(new IntVector(pos.getX(), pos.getY(), pos.getZ())) .direction(WrappedEnumDirection.valueOf(packet.b().name())) .digType(WPacketPlayInBlockDig.EnumPlayerDigType.valueOf(packet.c().name())) .build(); - - - - return bd; } @Override @@ -113,16 +99,12 @@ public class Processor_18 implements PacketConverter { BlockPosition pos = packet.a(); - WPacketPlayInBlockPlace bp = WPacketPlayInBlockPlace.builder() + return WPacketPlayInBlockPlace.builder() .blockPos(new IntVector(pos.getX(), pos.getY(), pos.getZ())) .direction(WrappedEnumDirection.values()[Math.min(packet.getFace(), 5)]) .itemStack(CraftItemStack.asCraftMirror(packet.getItemStack())) .vecX(packet.d()).vecY(packet.e()).vecZ(packet.f()) .build(); - - - - return bp; } @@ -132,22 +114,15 @@ public class Processor_18 implements PacketConverter { public WPacketPlayInCloseWindow processCloseWindow(Object object) { PacketPlayInCloseWindow packet = (PacketPlayInCloseWindow) object; - WPacketPlayInCloseWindow cw = WPacketPlayInCloseWindow.builder().id(fieldWindowId.get(packet)).build(); - - - - return cw; + return WPacketPlayInCloseWindow.builder().id(fieldWindowId.get(packet)).build(); } @Override public WPacketPlayInEntityAction processEntityAction(Object object) { PacketPlayInEntityAction packet = (PacketPlayInEntityAction) object; - WPacketPlayInEntityAction ea = WPacketPlayInEntityAction.builder().action(WPacketPlayInEntityAction.EnumPlayerAction + return WPacketPlayInEntityAction.builder().action(WPacketPlayInEntityAction.EnumPlayerAction .valueOf(packet.b().name())).build(); - - - return ea; } @Override @@ -160,15 +135,11 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - WPacketPlayOutEntityEffect ee = WPacketPlayOutEntityEffect.builder().entityId(serializer.e()) + return WPacketPlayOutEntityEffect.builder().entityId(serializer.e()) .effectId(serializer.readByte()) .amplifier(serializer.readByte()) .duration(serializer.e()) .flags(serializer.readByte()).build(); - - - - return ee; } @Override @@ -201,7 +172,8 @@ public class Processor_18 implements PacketConverter { } catch (IOException e) { throw new RuntimeException(e); } - WPacketPlayOutPosition p = WPacketPlayOutPosition.builder() + + return WPacketPlayOutPosition.builder() .x(serializer.readDouble()) .y(serializer.readDouble()) .z(serializer.readDouble()) @@ -211,10 +183,6 @@ public class Processor_18 implements PacketConverter { .map(f -> WPacketPlayOutPosition.EnumPlayerTeleportFlags.valueOf(f.name())) .collect(Collectors.toSet())) .build(); - - - - return p; } @Override @@ -228,16 +196,11 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - - WPacketPlayOutAttachEntity ae = WPacketPlayOutAttachEntity.builder() + return WPacketPlayOutAttachEntity.builder() .attachedEntityId(serial.readInt()) .holdingEntityId(serial.readInt()) .isLeashModifer((int)(serial.readUnsignedByte()) == 1) .build(); - - - - return ae; } @Override @@ -278,15 +241,11 @@ public class Processor_18 implements PacketConverter { looked = true; } - WPacketPlayOutEntity e = WPacketPlayOutEntity.builder() + return WPacketPlayOutEntity.builder() .id(id) .x(x / 32D).y(y / 32D).z(z / 32D).yaw(yaw / 256.0F * 360.0F).pitch(pitch / 256.0F * 360.0F) .onGround(ground).moved(moved).looked(looked) .build(); - - - - return e; } @Override @@ -364,7 +323,7 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - WPacketPlayOutEntityTeleport et = WPacketPlayOutEntityTeleport.builder() + return WPacketPlayOutEntityTeleport.builder() .entityId(serial.e()) .x(serial.readInt() / 32D) .y(serial.readInt() / 32D) @@ -373,9 +332,6 @@ public class Processor_18 implements PacketConverter { .pitch(serial.readByte() / 256.0F * 360.0F) .onGround(serial.readBoolean()) .build(); - - - return et; } @Override @@ -411,16 +367,12 @@ public class Processor_18 implements PacketConverter { throw new RuntimeException(e); } - WPacketHandshakingInSetProtocol isp = WPacketHandshakingInSetProtocol.builder() + return WPacketHandshakingInSetProtocol.builder() .versionNumber(serial.e()) .hostname(serial.c(32767)) .port(serial.readUnsignedShort()) .protocol(WPacketHandshakingInSetProtocol.EnumProtocol.valueOf(EnumProtocol.a(serial.e()).toString())) .build(); - - - - return isp; } @Override @@ -432,13 +384,11 @@ public class Processor_18 implements PacketConverter { IntVector vecPos = new IntVector(blockPos.getX(), blockPos.getY(), blockPos.getZ()); Material material = CraftMagicNumbers.getMaterial(packet.block.getBlock()); - WPacketPlayOutBlockChange change = WPacketPlayOutBlockChange.builder() + return WPacketPlayOutBlockChange.builder() .blockLocation(vecPos) .material(material) + .blockData((byte)packet.block.getBlock().toLegacyData(packet.block)) .build(); - - - return change; } @Override @@ -454,19 +404,17 @@ public class Processor_18 implements PacketConverter { short encodedloc = serial.readShort(); IntVector loc = new IntVector(encodedloc >> 12 & 15, encodedloc & 255, encodedloc >> 8 & 15); - Material blockType = CraftMagicNumbers.getMaterial(Block.d.a(serial.e()).getBlock()); + IBlockData blockData = Block.d.a(serial.e()); + Material blockType = CraftMagicNumbers.getMaterial(blockData.getBlock()); - blockChanges[i] = new WPacketPlayOutMultiBlockChange.BlockChange(loc, blockType); + blockChanges[i] = new WPacketPlayOutMultiBlockChange.BlockChange(loc, blockType, + (byte)blockData.getBlock().toLegacyData(blockData)); } - WPacketPlayOutMultiBlockChange change = WPacketPlayOutMultiBlockChange.builder() + return WPacketPlayOutMultiBlockChange.builder() .chunk(chunkLoc) .changes(blockChanges) .build(); - - - - return change; } @Override @@ -474,22 +422,19 @@ public class Processor_18 implements PacketConverter { PacketPlayOutEntityVelocity packet = (PacketPlayOutEntityVelocity) object; PacketDataSerializer serial = serialize(packet); - WPacketPlayOutEntityVelocity velocity = WPacketPlayOutEntityVelocity.builder() + return WPacketPlayOutEntityVelocity.builder() .entityId(serial.e()) .deltaX(serial.readShort() / 8000D) .deltaY(serial.readShort() / 8000D) .deltaZ(serial.readShort() / 8000D) .build(); - - - - return velocity; } @Override public WPacketPlayOutAbilities processOutAbilities(Object object) { PacketPlayOutAbilities packet = (PacketPlayOutAbilities) object; - WPacketPlayOutAbilities ab = WPacketPlayOutAbilities.builder() + + return WPacketPlayOutAbilities.builder() .capabilities(PlayerCapabilities.builder() .isInvulnerable(packet.a()) .isFlying(packet.b()) @@ -499,10 +444,6 @@ public class Processor_18 implements PacketConverter { .walkSpeed(outfieldWalkSpeed.get(packet)) .build()) .build(); - - - - return ab; } @Override @@ -535,7 +476,7 @@ public class Processor_18 implements PacketConverter { int[] data = new int[particle.d()]; - WPacketPlayOutWorldParticles part = WPacketPlayOutWorldParticles.builder() + val builder = WPacketPlayOutWorldParticles.builder() .particle(particle) .longD(serial.readBoolean()) .x(serial.readFloat()) @@ -545,13 +486,13 @@ public class Processor_18 implements PacketConverter { .offsetY(serial.readFloat()) .offsetZ(serial.readFloat()) .speed(serial.readFloat()) - .amount(serial.readInt()) - .data(Arrays.stream(data).map(i -> serial.e()).toArray()) - .build(); + .amount(serial.readInt()); + for (int i = 0; i < data.length; i++) { + data[i] = serial.e(); + } - - return part; + return builder.data(data).build(); } @Override @@ -565,12 +506,9 @@ public class Processor_18 implements PacketConverter { public WPacketPlayInChat processChat(Object object) { PacketPlayInChat packet = (PacketPlayInChat) object; - WPacketPlayInChat chat = WPacketPlayInChat.builder() + return WPacketPlayInChat.builder() .message(packet.a()) .build(); - - - return chat; } @Override @@ -580,7 +518,7 @@ public class Processor_18 implements PacketConverter { @Override public WPacketPlayOutPlayerInfo processInfo(Object object) { - PacketPlayOutPlayerInfo packet = (PacketPlayOutPlayerInfo) object; + return null; } @@ -689,13 +627,9 @@ public class Processor_18 implements PacketConverter { PacketDataSerializer serializer = serialize(packet); - WPacketPlayOutRemoveEntityEffect ree = WPacketPlayOutRemoveEntityEffect.builder() + return WPacketPlayOutRemoveEntityEffect.builder() .entityId(serializer.e()) .effect(PotionEffectType.getById(serializer.readUnsignedByte())).build(); - - - - return ree; } @Override @@ -725,12 +659,9 @@ public class Processor_18 implements PacketConverter { int entityId = serialized.e(); List watchedObject = DataWatcher.b(serialized); - WPacketPlayOutEntityMetadata em = WPacketPlayOutEntityMetadata.builder().entityId(entityId) + return WPacketPlayOutEntityMetadata.builder().entityId(entityId) .watchedObjects(watchedObject.stream().map(WrappedWatchableObject::new) .collect(Collectors.toList())).build(); - - - return em; } catch (IOException e) { throw new RuntimeException(e); } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutBlockChange.java b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutBlockChange.java index 351d613..f4759a4 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutBlockChange.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutBlockChange.java @@ -13,6 +13,7 @@ public class WPacketPlayOutBlockChange extends WPacket { private IntVector blockLocation; private Material material; + private byte blockData; @Override diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutMultiBlockChange.java b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutMultiBlockChange.java index c3880a0..be27df5 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutMultiBlockChange.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/out/WPacketPlayOutMultiBlockChange.java @@ -31,6 +31,7 @@ public class WPacketPlayOutMultiBlockChange extends WPacket { public static class BlockChange { private IntVector location; private Material material; + private byte data; @Override public String toString() { diff --git a/src/main/java/dev/brighten/ac/utils/BlockUtils.java b/src/main/java/dev/brighten/ac/utils/BlockUtils.java index 5455775..b8d6659 100644 --- a/src/main/java/dev/brighten/ac/utils/BlockUtils.java +++ b/src/main/java/dev/brighten/ac/utils/BlockUtils.java @@ -1,6 +1,9 @@ package dev.brighten.ac.utils; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.reflections.impl.MinecraftReflection; import dev.brighten.ac.utils.reflections.types.WrappedField; import org.bukkit.Bukkit; @@ -74,6 +77,37 @@ public class BlockUtils { return getBlockAsync(block.getLocation().clone().add(modX, modY, modZ)); } + public static Optional getWrappedBlock(APlayer player, Location location) { + if(player == null) { + return Optional.ofNullable(getBlockAsync(location.clone()) + .map(b -> new WrappedBlock(b.getLocation(), b.getType(), b.getData())).orElse(null)); + } + + return Optional.of(player.getBlockUpdateHandler() + .getBlock(new IntVector(location.getBlockX(), location.getBlockY(), location.getBlockZ()))); + } + + public static Optional getRelative(APlayer player, Location location, int modX, int modY, int modZ) { + if(player == null) { + return Optional.ofNullable(getBlockAsync(location.clone().add(modX, modY, modZ)) + .map(b -> new WrappedBlock(b.getLocation(), b.getType(), b.getData())).orElse(null)); + } + + return Optional.of(player.getBlockUpdateHandler() + .getRelative(new IntVector(location.getBlockX(), location.getBlockY(), location.getBlockZ()), + modX, modY, modZ)); + } + + public static Optional getRelative(APlayer player, Location location, BlockFace face, int distance) { + return getRelative(player, location, + face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance); + } + + public static Optional getRelative(APlayer player, Location location, BlockFace face) { + return getRelative(player, location, + face.getModX(), face.getModY(), face.getModZ()); + } + public static float getFriction(XMaterial material) { switch(material) { case SLIME_BLOCK: @@ -345,8 +379,12 @@ public class BlockUtils { return (block.getType().toString().contains("FENCE") && !block.getType().toString().contains("GATE")) | block.getType().toString().contains("WALL"); } + public static boolean isDoor(Material type) { + return type.toString().contains("DOOR") && !type.toString().contains("TRAP"); + } + public static boolean isDoor(Block block) { - return block.getType().toString().contains("DOOR") && !block.getType().toString().contains("TRAP"); + return isDoor(block.getType()); } public static boolean isBed(Block block) { diff --git a/src/main/java/dev/brighten/ac/utils/Helper.java b/src/main/java/dev/brighten/ac/utils/Helper.java index dd08783..9ee35bc 100644 --- a/src/main/java/dev/brighten/ac/utils/Helper.java +++ b/src/main/java/dev/brighten/ac/utils/Helper.java @@ -6,6 +6,7 @@ import dev.brighten.ac.packet.handler.HandlerAbstract; import dev.brighten.ac.packet.wrapper.objects.EnumParticle; import dev.brighten.ac.packet.wrapper.out.WPacketPlayOutWorldParticles; import dev.brighten.ac.utils.math.IntVector; +import dev.brighten.ac.utils.reflections.impl.MinecraftReflection; import dev.brighten.ac.utils.world.BlockData; import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.RayCollision; @@ -236,11 +237,11 @@ public class Helper { } public static List getCollisions(APlayer player, SimpleCollisionBox collisionBox) { - return getCollisions(player, collisionBox, Materials.SOLID); + return getCollisions(player, collisionBox, Materials.COLLIDABLE); } public static SimpleCollisionBox getEntityCollision(Entity entity) { - return new SimpleCollisionBox(ReflectionsUtil.getBoundingBox(entity)); + return new SimpleCollisionBox((Object)MinecraftReflection.getEntityBoundingBox(entity)); } public static List getCollisions(APlayer player, SimpleCollisionBox collisionBox, int mask) { @@ -255,11 +256,11 @@ public class Helper { for (int y = y1 - 1; y < y2; ++y) for (int z = z1; z < z2; ++z) { IntVector vec = new IntVector(x, y, z); - Material type = player.getBlockUpdateHandler().getPossibleMaterials(vec).getLast(); + Material type = player.getBlockUpdateHandler().getBlock(vec).getType(); if(type != Material.AIR && Materials.checkFlag(type, mask)) { CollisionBox box = BlockData.getData(type) - .getBox(player.getBukkitPlayer().getWorld(), vec, ProtocolVersion.getGameVersion()); + .getBox(player, vec, ProtocolVersion.getGameVersion()); if(box.isIntersected(collisionBox)) { box.downCast(collisionBoxes); diff --git a/src/main/java/dev/brighten/ac/utils/Materials.java b/src/main/java/dev/brighten/ac/utils/Materials.java index 8b19d3a..3e0a916 100644 --- a/src/main/java/dev/brighten/ac/utils/Materials.java +++ b/src/main/java/dev/brighten/ac/utils/Materials.java @@ -1,6 +1,7 @@ package dev.brighten.ac.utils; import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.utils.wrapper.Wrapper; import org.bukkit.Material; public class Materials { @@ -16,6 +17,7 @@ public class Materials { public static final int LIQUID = 0b00000000000000000000010000000; public static final int ICE = 0b00000000000000000000100000000; public static final int FENCE = 0b00000000000000000001000000000; + public static final int COLLIDABLE = 0b00000000000000000010000000000; static { for (int i = 0; i < MATERIAL_FLAGS.length; i++) { @@ -25,6 +27,11 @@ public class Materials { if (mat.isSolid() || mat.name().contains("COMPARATOR") || mat.name().contains("DIODE")) { MATERIAL_FLAGS[i] |= SOLID; } + + if(Wrapper.getInstance().isCollidable(mat)) { + MATERIAL_FLAGS[i] |= COLLIDABLE; + } + if (mat.name().endsWith("_STAIRS")) { MATERIAL_FLAGS[i] |= STAIRS; } @@ -34,7 +41,7 @@ public class Materials { } if(mat.name().contains("SKULL")) - MATERIAL_FLAGS[i] = SOLID; + MATERIAL_FLAGS[i] |= SOLID; if(mat.name().contains("STATIONARY") || mat.name().contains("LAVA") || mat.name().contains("WATER")) { if(mat.name().contains("LAVA")) { @@ -46,24 +53,22 @@ public class Materials { if(!mat.name().contains("GATE")) MATERIAL_FLAGS[mat.ordinal()] |= FENCE; } if(mat.name().contains("WALL")) MATERIAL_FLAGS[mat.ordinal()] |= WALL; - if(mat.name().contains("PLATE")) MATERIAL_FLAGS[mat.ordinal()] = 0; if(mat.name().contains("BED") && !mat.name().contains("ROCK")) MATERIAL_FLAGS[mat.ordinal()] |= SLABS; if(mat.name().contains("ICE")) MATERIAL_FLAGS[mat.ordinal()] |= ICE; - if(mat.name().contains("CARPET")) MATERIAL_FLAGS[mat.ordinal()] = SOLID; - if(mat.name().contains("SIGN")) MATERIAL_FLAGS[mat.ordinal()] = 0; + if(mat.name().contains("CARPET")) MATERIAL_FLAGS[mat.ordinal()] |= SOLID; } // fix some types where isSolid() returns the wrong value - MATERIAL_FLAGS[XMaterial.REPEATER.parseMaterial().ordinal()] = SOLID; - MATERIAL_FLAGS[XMaterial.SNOW.parseMaterial().ordinal()] = SOLID; - MATERIAL_FLAGS[XMaterial.ANVIL.parseMaterial().ordinal()] = SOLID; - MATERIAL_FLAGS[XMaterial.LILY_PAD.parseMaterial().ordinal()] = SOLID; + MATERIAL_FLAGS[XMaterial.REPEATER.parseMaterial().ordinal()] |= SOLID; + MATERIAL_FLAGS[XMaterial.SNOW.parseMaterial().ordinal()] |= SOLID; + MATERIAL_FLAGS[XMaterial.ANVIL.parseMaterial().ordinal()] |= SOLID; + MATERIAL_FLAGS[XMaterial.LILY_PAD.parseMaterial().ordinal()] |= SOLID; if(ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_8)) { - MATERIAL_FLAGS[XMaterial.SLIME_BLOCK.parseMaterial().ordinal()] = SOLID; + MATERIAL_FLAGS[XMaterial.SLIME_BLOCK.parseMaterial().ordinal()] |= SOLID; if(ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14)) { - MATERIAL_FLAGS[XMaterial.SCAFFOLDING.parseMaterial().ordinal()] = SOLID; + MATERIAL_FLAGS[XMaterial.SCAFFOLDING.parseMaterial().ordinal()] |= SOLID; } } diff --git a/src/main/java/dev/brighten/ac/utils/XMaterial.java b/src/main/java/dev/brighten/ac/utils/XMaterial.java index 88802d4..fe461b3 100644 --- a/src/main/java/dev/brighten/ac/utils/XMaterial.java +++ b/src/main/java/dev/brighten/ac/utils/XMaterial.java @@ -88,7 +88,6 @@ public enum XMaterial { ACTIVATOR_RAIL, /** * https://minecraft.gamepedia.com/Air - * {@link Material#isAir()} * * @see #VOID_AIR * @see #CAVE_AIR diff --git a/src/main/java/dev/brighten/ac/utils/math/IntVector.java b/src/main/java/dev/brighten/ac/utils/math/IntVector.java index 97d88a4..f681178 100644 --- a/src/main/java/dev/brighten/ac/utils/math/IntVector.java +++ b/src/main/java/dev/brighten/ac/utils/math/IntVector.java @@ -1,9 +1,12 @@ package dev.brighten.ac.utils.math; +import dev.brighten.ac.utils.MathHelper; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.util.Vector; @AllArgsConstructor @@ -13,6 +16,12 @@ public class IntVector { @Setter private int x, y, z; + public IntVector(Location location) { + this.x = MathHelper.floor_double(location.getX()); + this.y = MathHelper.floor_double(location.getY()); + this.z = MathHelper.floor_double(location.getZ()); + } + public IntVector clone() { return new IntVector(x, y, z); } @@ -26,6 +35,21 @@ public class IntVector { return "IntVector[" + x + ", " + y + ", " + z + "]"; } + public IntVector add(int x, int y, int z) { + this.x+= x; + this.y+= y; + this.z+= z; + return this; + } + + public IntVector add(IntVector vec) { + return add(vec.getX(), vec.getY(), vec.getZ()); + } + + public Location toLocation(World world) { + return new Location(world, x, y, z); + } + @Override public boolean equals(Object o) { if(!(o instanceof IntVector)) return false; diff --git a/src/main/java/dev/brighten/ac/utils/world/BlockData.java b/src/main/java/dev/brighten/ac/utils/world/BlockData.java index fbd29d6..a18d0fc 100644 --- a/src/main/java/dev/brighten/ac/utils/world/BlockData.java +++ b/src/main/java/dev/brighten/ac/utils/world/BlockData.java @@ -1,5 +1,7 @@ package dev.brighten.ac.utils.world; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.MiscUtils; @@ -9,7 +11,6 @@ import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.world.blocks.*; import dev.brighten.ac.utils.world.types.*; import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -19,7 +20,7 @@ import java.util.stream.Stream; public enum BlockData { _DEFAULT(new SimpleCollisionBox(0, 0, 0, 1, 1, 1), XMaterial.STONE.parseMaterial()), - _VINE((v, block) -> { + _VINE((v, protocol, block) -> { byte data = block.getData(); if((data & 4) == 4) @@ -50,11 +51,12 @@ public enum BlockData { new SimpleCollisionBox(0.4375, 0.0, 0.4375, 0.5625, 0.875, 0.5625) //top ), Material.BREWING_STAND), - _RAIL((protocol, b) -> ReflectionsUtil.getBlockBoundingBox(b).toCollisionBox(),Arrays.stream(Material.values()) + _RAIL((protocol, player, b) -> ReflectionsUtil.getBlockBoundingBox(BlockUtils.getBlock(b.getLocation())) + .toCollisionBox(),Arrays.stream(Material.values()) .filter(mat -> mat.name().toLowerCase().contains("rail")) .toArray(Material[]::new)), - _ANVIL((protocol, b) -> { + _ANVIL((protocol, player, b) -> { int dir = b.getData() & 0b01; CollisionBox box; if (dir == 1) { @@ -70,7 +72,7 @@ public enum BlockData { .map(BlockData::m) .toArray(Material[]::new)), - _SKULL((protocol, b) -> { + _SKULL((protocol, player, b) -> { int rotation = b.getData() & 7; CollisionBox box; @@ -103,13 +105,13 @@ public enum BlockData { .toArray(Material[]::new)), _HOPPER(new HopperBounding(), XMaterial.HOPPER.parseMaterial()), - _CAKE((protocol, block) -> { + _CAKE((protocol, player, block) -> { double f1 = (1 + block.getData() * 2) / 16D; return new SimpleCollisionBox(f1, 0, 0.0625, 1 - 0.0625, 0.5, 1 - 0.0625); }, Arrays.stream(Material.values()).filter(m -> m.name().contains("CAKE")).toArray(Material[]::new)), - _LADDER((protocol, b) -> { + _LADDER((protocol, player, b) -> { CollisionBox box = NoCollisionBox.INSTANCE; float var3 = 0.125F; @@ -126,7 +128,7 @@ public enum BlockData { return box; }, XMaterial.LADDER.parseMaterial()), - _FENCE_GATE((protocol, b) -> { + _FENCE_GATE((protocol, player, b) -> { byte var5 = b.getData(); CollisionBox box = NoCollisionBox.INSTANCE; @@ -150,13 +152,13 @@ public enum BlockData { MiscUtils.match("IRON_FENCE"), MiscUtils.match("IRON_BARS")), - _SNOW((protocol, b) -> { + _SNOW((protocol, player, b) -> { int height = (b.getData() & 0b1111); if (height == 0) return new SimpleCollisionBox(0, 0, 0, 1, 0, 1); // return NoCollisionBox.INSTANCE; return new SimpleCollisionBox(0, 0, 0, 1, height * 0.125, 1); }, XMaterial.SNOW.parseMaterial()), - _SLAB((protocol, b) -> { + _SLAB((protocol, player, b) -> { if ((b.getData() & 8) == 0) return new SimpleCollisionBox(0, 0, 0, 1, .5, 1); else return new SimpleCollisionBox(0, .5, 0, 1, 1, 1); @@ -165,35 +167,25 @@ public enum BlockData { .filter(mat -> !mat.name().contains("DOUBLE")) .toArray(Material[]::new)), - _STAIR((protocol, b) -> { - boolean inverted = (b.getData() & 4) != 0; - int dir = (b.getData() & 0b11); - SimpleCollisionBox top; - SimpleCollisionBox bottom = new SimpleCollisionBox(0, 0, 0, 1, .5, 1); - if (dir == 0) top = new SimpleCollisionBox(.5, .5, 0, 1, 1, 1); - else if (dir == 1) top = new SimpleCollisionBox(0, .5, 0, .5, 1, 1); - else if (dir == 2) top = new SimpleCollisionBox(0, .5, .5, 1, 1, 1); - else top = new SimpleCollisionBox(0, .5, 0, 1, 1, .5); - if (inverted) { - top.offset(0, -.5, 0); - bottom.offset(0, .5, 0); - } - return new ComplexCollisionBox(top, bottom); - }, Arrays.stream(XMaterial.values()).filter(mat -> mat.name().contains("STAIRS")) + _STAIR(new DynamicStair(), Arrays.stream(XMaterial.values()).filter(mat -> mat.name().contains("STAIRS")) .map(BlockData::m) .toArray(Material[]::new)), - _CHEST((protocol, b) -> { - if (b.getRelative(BlockFace.NORTH).getType().name().contains("CHEST")) { + _CHEST((protocol, player, b) -> { + if (player.getBlockUpdateHandler().getRelative(new IntVector(b.getLocation()), BlockFace.NORTH) + .getType().name().contains("CHEST")) { return new SimpleCollisionBox(0.0625F, 0.0F, 0.0F, 0.9375F, 0.875F, 0.9375F); - } else if (b.getRelative(BlockFace.SOUTH).getType().name().contains("CHEST")) { + } else if (player.getBlockUpdateHandler().getRelative(new IntVector(b.getLocation()), BlockFace.SOUTH) + .getType().name().contains("CHEST")) { return new SimpleCollisionBox(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 1.0F); - } else if (b.getRelative(BlockFace.WEST).getType().name().contains("CHEST")) { + } else if (player.getBlockUpdateHandler().getRelative(new IntVector(b.getLocation()), BlockFace.WEST) + .getType().name().contains("CHEST")) { return new SimpleCollisionBox(0.0F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); - } else if (b.getRelative(BlockFace.EAST).getType().name().contains("CHEST")) { + } else if (player.getBlockUpdateHandler().getRelative(new IntVector(b.getLocation()), BlockFace.EAST) + .getType().name().contains("CHEST")) { return new SimpleCollisionBox(0.0625F, 0.0F, 0.0625F, 1.0F, 0.875F, 0.9375F); } else { @@ -215,7 +207,7 @@ public enum BlockData { Arrays.stream(Material.values()).filter(m -> m.name().contains("CARPET")).toArray(Material[]::new)), _Daylight(new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.375, 1.0F), MiscUtils.match("DAYLIGHT_DETECTOR"), MiscUtils.match("DAYLIGHT_DETECTOR_INVERTED")), - _LILIPAD((v, b) -> { + _LILIPAD((v, player, b) -> { if (v.isBelow(ProtocolVersion.V1_9)) return new SimpleCollisionBox(0.0f, 0.0F, 0.0f, 1.0f, 0.015625F, 1.0f); return new SimpleCollisionBox(0.0625, 0.0F, 0.0625, 0.9375, 0.015625F, 0.9375); @@ -240,7 +232,7 @@ public enum BlockData { XMaterial.STRUCTURE_VOID.parseMaterial()), _END_ROD(new DynamicRod(), XMaterial.END_ROD.parseMaterial()), - _CAULDRON(new CouldronBounding(), XMaterial.CAULDRON.parseMaterial()), + _CAULDRON(new CouldronBounding(), Material.CAULDRON), _CACTUS(new SimpleCollisionBox(0.0625, 0, 0.0625, 1 - 0.0625, 1 - 0.0625, 1 - 0.0625), XMaterial.CACTUS.parseMaterial()), _PISTON_BASE(new PistonBaseCollision(), m(XMaterial.PISTON), m(XMaterial.STICKY_PISTON)), @@ -249,10 +241,10 @@ public enum BlockData { _SOULSAND(new SimpleCollisionBox(0, 0, 0, 1, 0.875, 1), XMaterial.SOUL_SAND.parseMaterial()), - _CAMPFIRE((version, block) -> version.isOrAbove(ProtocolVersion.V1_14) + _CAMPFIRE((version, player, block) -> version.isOrAbove(ProtocolVersion.V1_14) ? new SimpleCollisionBox(0,0,0, 1, 0.4375, 1) : NoCollisionBox.INSTANCE, XMaterial.CAMPFIRE.parseMaterial()), - _LECTERN((version, block) -> { + _LECTERN((version, player, block) -> { if(ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14)) { return new ComplexCollisionBox( new SimpleCollisionBox(0, 0.9375, 0, 1, 0.9375, 1), @@ -261,9 +253,9 @@ public enum BlockData { } else return NoCollisionBox.INSTANCE; }, XMaterial.LECTERN.parseMaterial()), _POT(new SimpleCollisionBox(0.3125, 0.0, 0.3125, 0.6875, 0.375, 0.6875), - XMaterial.FLOWER_POT.parseMaterial()), + Material.FLOWER_POT), - _WALL_SIGN((version, block) -> { + _WALL_SIGN((version, player, block) -> { byte data = block.getData(); double var4 = 0.28125; @@ -311,7 +303,7 @@ public enum BlockData { _SIGN(new SimpleCollisionBox(0.25, 0.0, 0.25, 0.75, 1.0, 0.75), Arrays.stream(Material.values()).filter(m -> m.name().endsWith("_SIGN") || m.name().startsWith("SIGN")) .toArray(Material[]::new)), - _BUTTON((version, block) -> { + _BUTTON((version, player, block) -> { BlockFace face; switch(block.getData() & 7) { case 0: @@ -356,7 +348,7 @@ public enum BlockData { return NoCollisionBox.INSTANCE; }, Arrays.stream(Material.values()).filter(mat -> mat.name().contains("BUTTON")).toArray(Material[]::new)), - _LEVER((version, block) -> { + _LEVER((version, player, block) -> { byte data = (byte)(block.getData() & 7); BlockFace face; switch(data) { @@ -440,14 +432,14 @@ public enum BlockData { public CollisionBox getBox(Block block, ProtocolVersion version) { if (this.box != null) return this.box.copy().offset(block.getX(), block.getY(), block.getZ()); - return new DynamicCollisionBox(dynamic, block, version).offset(block.getX(), block.getY(), block.getZ()); + return new DynamicCollisionBox(dynamic, null, new WrappedBlock(block.getLocation(), + block.getType(), block.getData()), version).offset(block.getX(), block.getY(), block.getZ()); } - public CollisionBox getBox(World world, IntVector block, ProtocolVersion version) { + public CollisionBox getBox(APlayer player, IntVector block, ProtocolVersion version) { if (this.box != null) return this.box.copy().offset(block.getX(), block.getY(), block.getZ()); - return new DynamicCollisionBox(dynamic, - BlockUtils.getBlockAsync(block.toBukkitVector().toLocation(world)).orElse(null), version) + return new DynamicCollisionBox(dynamic, null, player.getBlockUpdateHandler().getBlock(block), version) .offset(block.getX(), block.getY(), block.getZ()); } diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DoorHandler.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DoorHandler.java index 4cb9177..1fef635 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DoorHandler.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DoorHandler.java @@ -1,46 +1,36 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.NoCollisionBox; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.material.Door; -import org.bukkit.material.MaterialData; import java.util.Optional; public class DoorHandler implements CollisionFactory { @Override - public CollisionBox fetch(ProtocolVersion version, Block b) { + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock b) { if(ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_13)) { - Door state = (Door) b.getState().getData(); + Door state = new Door(b.getType(), b.getData()); byte data = state.getData(); if (( data & 0b01000 ) != 0) { - Optional rel = BlockUtils.getRelativeAsync(b, BlockFace.DOWN); + Optional rel = BlockUtils.getRelative(player, b.getLocation(), BlockFace.DOWN); - if(!rel.isPresent()) return NoCollisionBox.INSTANCE; - MaterialData state2 = rel.get().getState().getData(); - if (state2 instanceof Door) { - data = state2.getData(); - } - else { - return NoCollisionBox.INSTANCE; - } + if(rel.isPresent() && BlockUtils.isDoor(rel.get().getType())) { + data = rel.get().getData(); + } else return NoCollisionBox.INSTANCE; } else { - Optional rel = BlockUtils.getRelativeAsync(b, BlockFace.UP); + Optional rel = BlockUtils.getRelative(player, b.getLocation(), BlockFace.UP); - if(!rel.isPresent()) return NoCollisionBox.INSTANCE; - MaterialData state2 = rel.get().getState().getData(); - if (state2 instanceof Door) { - state = (Door) state2; - } - else { - return NoCollisionBox.INSTANCE; - } + if(rel.isPresent() && BlockUtils.isDoor(rel.get().getType())) { + state = new Door(rel.get().getType(), rel.get().getData()); + } else return NoCollisionBox.INSTANCE; } SimpleCollisionBox box; @@ -95,23 +85,20 @@ public class DoorHandler implements CollisionFactory { // box.offset(0,1,0); return box; } else { - Block blockTwo; + WrappedBlock blockTwo; Door door = (Door) b.getType().getNewData(b.getData()); if (door.isTopHalf()) { - Optional rel = BlockUtils.getRelativeAsync(b, BlockFace.DOWN); + Optional rel = BlockUtils.getRelative(player, b.getLocation(), BlockFace.DOWN); - if (!rel.isPresent()) return NoCollisionBox.INSTANCE; - - if (BlockUtils.isDoor(rel.get())) { + if (rel.isPresent() && BlockUtils.isDoor(rel.get().getType())) { blockTwo = rel.get(); } else { return NoCollisionBox.INSTANCE; } } else if (ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_13)) { - Optional rel = BlockUtils.getRelativeAsync(b, BlockFace.UP); + Optional rel = BlockUtils.getRelative(player, b.getLocation(), BlockFace.UP); - if (!rel.isPresent()) return NoCollisionBox.INSTANCE; - if (BlockUtils.isDoor(rel.get())) { + if (rel.isPresent() && BlockUtils.isDoor(rel.get().getType())) { blockTwo = rel.get(); } else { return NoCollisionBox.INSTANCE; diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java index 5b21c38..bef5501 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicFence.java @@ -1,5 +1,7 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.Materials; @@ -9,9 +11,7 @@ import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.ComplexCollisionBox; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; import java.util.Optional; @@ -22,12 +22,12 @@ public class DynamicFence implements CollisionFactory { private static final double max = .5 + width; @Override - public CollisionBox fetch(ProtocolVersion version, Block b) { + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock b) { ComplexCollisionBox box = new ComplexCollisionBox(new SimpleCollisionBox(min, 0, min, max, 1.5, max)); - boolean east = fenceConnects(version, b, BlockFace.EAST ); - boolean north = fenceConnects(version, b, BlockFace.NORTH); - boolean south = fenceConnects(version, b, BlockFace.SOUTH); - boolean west = fenceConnects(version, b, BlockFace.WEST ); + boolean east = fenceConnects(version, player, b, BlockFace.EAST); + boolean north = fenceConnects(version, player, b, BlockFace.NORTH); + boolean south = fenceConnects(version, player, b, BlockFace.SOUTH); + boolean west = fenceConnects(version, player, b, BlockFace.WEST); if (east) box.add(new SimpleCollisionBox(max, 0, min, 1, 1.5, max)); if (west) box.add(new SimpleCollisionBox(0, 0, min, max, 1.5, max)); if (north) box.add(new SimpleCollisionBox(min, 0, 0, max, 1.5, min)); @@ -52,14 +52,13 @@ public class DynamicFence implements CollisionFactory { } } - private static boolean fenceConnects(ProtocolVersion v,Block fenceBlock, BlockFace direction) { - BlockUtils.getRelativeAsync(fenceBlock, direction, 1); - Optional targetBlock = BlockUtils.getRelativeAsync(fenceBlock, direction, 1); + private static boolean fenceConnects(ProtocolVersion v, APlayer player, WrappedBlock fenceBlock, BlockFace direction) { + Optional targetBlock = BlockUtils.getRelative(player, fenceBlock.getLocation(), direction, 1); + + if(targetBlock.isEmpty()) return false; - if(!targetBlock.isPresent()) return false; - BlockState sFence = fenceBlock.getState(); Material target = targetBlock.get().getType(); - Material fence = sFence.getType(); + Material fence = fenceBlock.getType(); if (!isFence(target)&&isBlacklisted(target)) return false; diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java index b76411d..aa6e18f 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicPane.java @@ -1,5 +1,7 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.Materials; @@ -9,9 +11,10 @@ import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.ComplexCollisionBox; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import java.util.Optional; + @SuppressWarnings("Duplicates") public class DynamicPane implements CollisionFactory { @@ -20,12 +23,12 @@ public class DynamicPane implements CollisionFactory { private static final double max = .5 + width; @Override - public CollisionBox fetch(ProtocolVersion version, Block b) { + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock b) { ComplexCollisionBox box = new ComplexCollisionBox(new SimpleCollisionBox(min, 0, min, max, 1, max)); - boolean east = fenceConnects(version,b, BlockFace.EAST ); - boolean north = fenceConnects(version,b, BlockFace.NORTH); - boolean south = fenceConnects(version,b, BlockFace.SOUTH); - boolean west = fenceConnects(version,b, BlockFace.WEST ); + boolean east = fenceConnects(version, player, b, BlockFace.EAST); + boolean north = fenceConnects(version, player, b, BlockFace.NORTH); + boolean south = fenceConnects(version, player, b, BlockFace.SOUTH); + boolean west = fenceConnects(version, player, b, BlockFace.WEST); if (version.isBelow(ProtocolVersion.V1_9) && !(east||north||south||west)) { east = true; @@ -42,9 +45,11 @@ public class DynamicPane implements CollisionFactory { } - private static boolean fenceConnects(ProtocolVersion v, Block fenceBlock, BlockFace direction) { - Block targetBlock = fenceBlock.getRelative(direction,1); - Material target = targetBlock.getType(); + private static boolean fenceConnects(ProtocolVersion v, APlayer player, WrappedBlock fenceBlock, BlockFace direction) { + Optional targetBlock = BlockUtils.getRelative(player, fenceBlock.getLocation(), direction, 1); + + if(targetBlock.isEmpty()) return false; + Material target = targetBlock.get().getType(); if (!isPane(target)&&DynamicFence.isBlacklisted(target)) return false; diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicRod.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicRod.java index ab0ba70..28168ff 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicRod.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicRod.java @@ -1,10 +1,11 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; -import org.bukkit.block.Block; @SuppressWarnings("Duplicates") public class DynamicRod implements CollisionFactory { @@ -14,7 +15,7 @@ public class DynamicRod implements CollisionFactory { public static final CollisionBox NS = new SimpleCollisionBox(0.4375, 0.4375, 0, 0.5625, 0.625, 1); @Override - public CollisionBox fetch(ProtocolVersion version, Block b) { + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock b) { switch (b.getData()) { case 0: case 1: diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java new file mode 100644 index 0000000..a1397bf --- /dev/null +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java @@ -0,0 +1,167 @@ +package dev.brighten.ac.utils.world.blocks; + + +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; +import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.packet.wrapper.objects.WrappedEnumDirection; +import dev.brighten.ac.utils.BlockUtils; +import dev.brighten.ac.utils.Materials; +import dev.brighten.ac.utils.world.CollisionBox; +import dev.brighten.ac.utils.world.types.CollisionFactory; +import dev.brighten.ac.utils.world.types.ComplexCollisionBox; +import dev.brighten.ac.utils.world.types.HexCollisionBox; +import org.bukkit.block.BlockFace; + +import java.util.Optional; +import java.util.stream.IntStream; + +public class DynamicStair implements CollisionFactory { + protected static final CollisionBox TOP_AABB = new HexCollisionBox(0, 8, 0, 16, 16, 16); + protected static final CollisionBox BOTTOM_AABB = new HexCollisionBox(0, 0, 0, 16, 8, 16); + protected static final CollisionBox OCTET_NNN = new HexCollisionBox(0.0D, 0.0D, 0.0D, 8.0D, 8.0D, 8.0D); + protected static final CollisionBox OCTET_NNP = new HexCollisionBox(0.0D, 0.0D, 8.0D, 8.0D, 8.0D, 16.0D); + protected static final CollisionBox OCTET_NPN = new HexCollisionBox(0.0D, 8.0D, 0.0D, 8.0D, 16.0D, 8.0D); + protected static final CollisionBox OCTET_NPP = new HexCollisionBox(0.0D, 8.0D, 8.0D, 8.0D, 16.0D, 16.0D); + protected static final CollisionBox OCTET_PNN = new HexCollisionBox(8.0D, 0.0D, 0.0D, 16.0D, 8.0D, 8.0D); + protected static final CollisionBox OCTET_PNP = new HexCollisionBox(8.0D, 0.0D, 8.0D, 16.0D, 8.0D, 16.0D); + protected static final CollisionBox OCTET_PPN = new HexCollisionBox(8.0D, 8.0D, 0.0D, 16.0D, 16.0D, 8.0D); + protected static final CollisionBox OCTET_PPP = new HexCollisionBox(8.0D, 8.0D, 8.0D, 16.0D, 16.0D, 16.0D); + protected static final CollisionBox[] TOP_SHAPES = makeShapes(TOP_AABB, OCTET_NNN, OCTET_PNN, OCTET_NNP, OCTET_PNP); + protected static final CollisionBox[] BOTTOM_SHAPES = makeShapes(BOTTOM_AABB, OCTET_NPN, OCTET_PPN, OCTET_NPP, OCTET_PPP); + private static final int[] SHAPE_BY_STATE = new int[]{12, 5, 3, 10, 14, 13, 7, 11, 13, 7, 11, 14, 8, 4, 1, 2, 4, 1, 2, 8}; + + public static EnumShape getStairsShape(APlayer player, WrappedBlock originalStairs) { + BlockFace facing = BlockFace.valueOf(WrappedEnumDirection.fromType1(5 - (originalStairs.getData() & 3)) + .name()); + Optional offsetOne = BlockUtils.getRelative(player, originalStairs.getLocation(), facing); + + if(!offsetOne.isPresent()) return EnumShape.STRAIGHT; + + if (Materials.checkFlag(offsetOne.get().getType(), Materials.STAIRS) + && (originalStairs.getData() & 4) == (offsetOne.get().getData() & 4)) { + BlockFace enumfacing1 = BlockFace.valueOf(WrappedEnumDirection.fromType1(5 - (offsetOne.get().getData() & 3)) + .name()); + + if (isDifferentAxis(facing, enumfacing1) && canTakeShape(player, originalStairs, enumfacing1.getOppositeFace().getModX(), enumfacing1.getOppositeFace().getModY(), enumfacing1.getOppositeFace().getModZ())) { + if (enumfacing1 == rotateYCCW(facing)) { + return EnumShape.OUTER_LEFT; + } + + return EnumShape.OUTER_RIGHT; + } + } + + Optional offsetTwo = BlockUtils.getRelative(player, originalStairs.getLocation(), + facing.getOppositeFace().getModX(), + facing.getOppositeFace().getModY(), facing.getOppositeFace().getModZ()); + + if(!offsetTwo.isPresent()) return EnumShape.STRAIGHT; + + if (Materials.checkFlag(offsetTwo.get().getType(), Materials.STAIRS) + && (originalStairs.getData() & 4) == (offsetTwo.get().getData() & 4)) { + BlockFace enumfacing2 = BlockFace.valueOf(WrappedEnumDirection.fromType1(5 - (offsetTwo.get().getData() & 3)) + .name()); + + if (isDifferentAxis(facing, enumfacing2) && canTakeShape(player, originalStairs, enumfacing2.getModX(), enumfacing2.getModY(), enumfacing2.getModZ())) { + if (enumfacing2 == rotateYCCW(facing)) { + return EnumShape.INNER_LEFT; + } + + return EnumShape.INNER_RIGHT; + } + } + + return EnumShape.STRAIGHT; + } + + private static boolean canTakeShape(APlayer player, WrappedBlock stairOne, int ax, int ay, int az) { + Optional otherStair = BlockUtils.getRelative(player, stairOne.getLocation(), ax, ay, az); + return !otherStair.isPresent() || !Materials.checkFlag(otherStair.get().getType(), Materials.STAIRS) || + (stairOne.getData() & 3) != (otherStair.get().getData() & 3) || + (stairOne.getData() & 4) != (otherStair.get().getData() & 4); + } + + private static boolean isDifferentAxis(BlockFace faceOne, BlockFace faceTwo) { + return faceOne.getOppositeFace() != faceTwo && faceOne != faceTwo; + } + + private static BlockFace rotateYCCW(BlockFace face) { + switch (face) { + default: + case NORTH: + return BlockFace.WEST; + case EAST: + return BlockFace.NORTH; + case SOUTH: + return BlockFace.EAST; + case WEST: + return BlockFace.SOUTH; + } + } + + private static CollisionBox[] makeShapes(CollisionBox p_199779_0_, CollisionBox p_199779_1_, CollisionBox p_199779_2_, CollisionBox p_199779_3_, CollisionBox p_199779_4_) { + return IntStream.range(0, 16).mapToObj((p_199780_5_) -> makeStairShape(p_199780_5_, p_199779_0_, p_199779_1_, p_199779_2_, p_199779_3_, p_199779_4_)).toArray(CollisionBox[]::new); + } + + private static CollisionBox makeStairShape(int p_199781_0_, CollisionBox p_199781_1_, CollisionBox p_199781_2_, CollisionBox p_199781_3_, CollisionBox p_199781_4_, CollisionBox p_199781_5_) { + ComplexCollisionBox voxelshape = new ComplexCollisionBox(p_199781_1_); + if ((p_199781_0_ & 1) != 0) { + voxelshape.add(p_199781_2_); + } + + if ((p_199781_0_ & 2) != 0) { + voxelshape.add(p_199781_3_); + } + + if ((p_199781_0_ & 4) != 0) { + voxelshape.add(p_199781_4_); + } + + if ((p_199781_0_ & 8) != 0) { + voxelshape.add(p_199781_5_); + } + + return voxelshape; + } + + @Override + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock block) { + int shapeOrdinal; + // If server is 1.13+ and client is also 1.13+, we can read the block's data directly + EnumShape shape = getStairsShape(player, block); + shapeOrdinal = shape.ordinal(); + return ((block.getData() & 4) > 0 ? TOP_SHAPES : BOTTOM_SHAPES)[SHAPE_BY_STATE[getShapeIndex(block, shapeOrdinal)]].copy(); + } + + private int getShapeIndex(WrappedBlock state, int shapeOrdinal) { + return shapeOrdinal * 4 + directionToValue(BlockFace.valueOf(WrappedEnumDirection + .fromType1(5 - (state.getData() & 3)) + .name())); + } + + private int directionToValue(BlockFace face) { + switch (face) { + default: + case UP: + case DOWN: + return -1; + case NORTH: + return 2; + case SOUTH: + return 0; + case WEST: + return 1; + case EAST: + return 3; + } + } + + enum EnumShape { + STRAIGHT, + INNER_LEFT, + INNER_RIGHT, + OUTER_LEFT, + OUTER_RIGHT + } +} diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java index 5b59bf8..af01860 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java @@ -1,5 +1,7 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.Materials; @@ -7,7 +9,6 @@ import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import java.util.Optional; @@ -20,11 +21,11 @@ public class DynamicWall implements CollisionFactory { private static final double max = .5 + width; @Override - public CollisionBox fetch(ProtocolVersion version, Block b) { - boolean var3 = wallConnects(version, b, BlockFace.NORTH); - boolean var4 = wallConnects(version, b, BlockFace.SOUTH); - boolean var5 = wallConnects(version, b, BlockFace.WEST); - boolean var6 = wallConnects(version, b, BlockFace.EAST); + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock b) { + boolean var3 = wallConnects(version, player, b, BlockFace.NORTH); + boolean var4 = wallConnects(version, player, b, BlockFace.SOUTH); + boolean var5 = wallConnects(version, player, b, BlockFace.WEST); + boolean var6 = wallConnects(version, player, b, BlockFace.EAST); double var7 = 0.25; double var8 = 0.75; @@ -58,11 +59,11 @@ public class DynamicWall implements CollisionFactory { return new SimpleCollisionBox(var7, 0.0, var9, var8, 1.5, var10); } + private static boolean wallConnects(ProtocolVersion v, APlayer player, WrappedBlock fenceBlock, BlockFace direction) { + Optional targetBlock = BlockUtils.getRelative(player, fenceBlock.getLocation(), direction, 1); - private static boolean wallConnects(ProtocolVersion v, Block fenceBlock, BlockFace direction) { - Optional targetBlock = BlockUtils.getRelativeAsync(fenceBlock, direction, 1); + if(targetBlock.isEmpty()) return false; - if(!targetBlock.isPresent()) return false; Material target = targetBlock.get().getType(); if (!isWall(target)&&DynamicFence.isBlacklisted(target)) diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/PistonBaseCollision.java b/src/main/java/dev/brighten/ac/utils/world/blocks/PistonBaseCollision.java index 5c98c2d..68ea06b 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/PistonBaseCollision.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/PistonBaseCollision.java @@ -1,15 +1,16 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; -import org.bukkit.block.Block; public class PistonBaseCollision implements CollisionFactory { @Override - public CollisionBox fetch(ProtocolVersion version, Block block) { - byte data = block.getState().getData().getData(); + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock block) { + byte data = block.getData(); if ((data & 8) != 0) { switch (data & 7) { diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/PistonDickCollision.java b/src/main/java/dev/brighten/ac/utils/world/blocks/PistonDickCollision.java index c2cade6..405e6a3 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/PistonDickCollision.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/PistonDickCollision.java @@ -1,18 +1,19 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.ComplexCollisionBox; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; -import org.bukkit.block.Block; public class PistonDickCollision implements CollisionFactory { public static final int[] offsetsXForSide = new int[]{0, 0, 0, 0, -1, 1}; @Override - public CollisionBox fetch(ProtocolVersion version, Block block) { - byte data = block.getState().getData().getData(); + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock block) { + byte data = block.getData(); switch (clamp_int(data & 7, 0, offsetsXForSide.length - 1)) { case 0: diff --git a/src/main/java/dev/brighten/ac/utils/world/blocks/TrapDoorHandler.java b/src/main/java/dev/brighten/ac/utils/world/blocks/TrapDoorHandler.java index 9fa5222..9dfd0be 100644 --- a/src/main/java/dev/brighten/ac/utils/world/blocks/TrapDoorHandler.java +++ b/src/main/java/dev/brighten/ac/utils/world/blocks/TrapDoorHandler.java @@ -1,15 +1,16 @@ package dev.brighten.ac.utils.world.blocks; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.world.CollisionBox; import dev.brighten.ac.utils.world.types.CollisionFactory; import dev.brighten.ac.utils.world.types.SimpleCollisionBox; -import org.bukkit.block.Block; public class TrapDoorHandler implements CollisionFactory { @Override - public CollisionBox fetch(ProtocolVersion version, Block block) { - byte data = block.getState().getData().getData(); + public CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock block) { + byte data = block.getData(); double var2 = 0.1875; if ((data & 4) != 0) { diff --git a/src/main/java/dev/brighten/ac/utils/world/types/CollisionFactory.java b/src/main/java/dev/brighten/ac/utils/world/types/CollisionFactory.java index 4b52da4..6e43dde 100644 --- a/src/main/java/dev/brighten/ac/utils/world/types/CollisionFactory.java +++ b/src/main/java/dev/brighten/ac/utils/world/types/CollisionFactory.java @@ -1,9 +1,10 @@ package dev.brighten.ac.utils.world.types; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.utils.world.CollisionBox; -import org.bukkit.block.Block; public interface CollisionFactory { - CollisionBox fetch(ProtocolVersion version, Block block); + CollisionBox fetch(ProtocolVersion version, APlayer player, WrappedBlock block); } \ No newline at end of file diff --git a/src/main/java/dev/brighten/ac/utils/world/types/DynamicCollisionBox.java b/src/main/java/dev/brighten/ac/utils/world/types/DynamicCollisionBox.java index 08c02ef..c3601e1 100644 --- a/src/main/java/dev/brighten/ac/utils/world/types/DynamicCollisionBox.java +++ b/src/main/java/dev/brighten/ac/utils/world/types/DynamicCollisionBox.java @@ -1,10 +1,11 @@ package dev.brighten.ac.utils.world.types; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.objects.EnumParticle; import dev.brighten.ac.utils.world.CollisionBox; import lombok.Setter; -import org.bukkit.block.Block; import org.bukkit.entity.Player; import java.util.List; @@ -12,31 +13,33 @@ import java.util.List; public class DynamicCollisionBox implements CollisionBox { private final CollisionFactory box; + private APlayer player; @Setter - private Block block; + private WrappedBlock block; @Setter private ProtocolVersion version; private double x,y,z; - public DynamicCollisionBox(CollisionFactory box, Block block, ProtocolVersion version) { + public DynamicCollisionBox(CollisionFactory box, APlayer player, WrappedBlock block, ProtocolVersion version) { this.box = box; + this.player = player; this.block = block; this.version = version; } @Override public boolean isCollided(CollisionBox other) { - return box.fetch(version, block).offset(x,y,z).isCollided(other); + return box.fetch(version, player, block).offset(x,y,z).isCollided(other); } @Override public boolean isIntersected(CollisionBox other) { - return box.fetch(version, block).offset(x, y, z).isIntersected(other); + return box.fetch(version, player, block).offset(x, y, z).isIntersected(other); } @Override public DynamicCollisionBox copy() { - return new DynamicCollisionBox(box,block,version).offset(x,y,z); + return new DynamicCollisionBox(box, player, block, version).offset(x,y,z); } @Override @@ -59,16 +62,16 @@ public class DynamicCollisionBox implements CollisionBox { @Override public void draw(EnumParticle particle, Player... players) { - box.fetch(version, block).offset(x,y,z).draw(particle,players); + box.fetch(version, player, block).offset(x,y,z).draw(particle,players); } @Override public void downCast(List list) { - box.fetch(version,block).offset(x,y,z).downCast(list); + box.fetch(version, player, block).offset(x,y,z).downCast(list); } @Override public boolean isNull() { - return box.fetch(version,block).isNull(); + return box.fetch(version, player, block).isNull(); } } \ No newline at end of file diff --git a/src/main/java/dev/brighten/ac/utils/world/types/HexCollisionBox.java b/src/main/java/dev/brighten/ac/utils/world/types/HexCollisionBox.java new file mode 100644 index 0000000..b1dcb62 --- /dev/null +++ b/src/main/java/dev/brighten/ac/utils/world/types/HexCollisionBox.java @@ -0,0 +1,12 @@ +package dev.brighten.ac.utils.world.types; + +public class HexCollisionBox extends SimpleCollisionBox { + public HexCollisionBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { + this.minX = minX / 16d; + this.minY = minY / 16d; + this.minZ = minZ / 16d; + this.maxX = maxX / 16d; + this.maxY = maxY / 16d; + this.maxZ = maxZ / 16d; + } +} diff --git a/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java b/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java index 0c4cb45..5f0825a 100644 --- a/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java +++ b/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java @@ -162,7 +162,7 @@ public class RayCollision implements CollisionBox { final Material type = block.getType(); - if (!Materials.checkFlag(type, Materials.SOLID)) continue; + if (!Materials.checkFlag(type, Materials.COLLIDABLE)) continue; CollisionBox box = BlockData.getData(type).getBox(block, version); diff --git a/src/main/java/dev/brighten/ac/utils/wrapper/Wrapper.java b/src/main/java/dev/brighten/ac/utils/wrapper/Wrapper.java index db6cd7a..8c1b1e0 100644 --- a/src/main/java/dev/brighten/ac/utils/wrapper/Wrapper.java +++ b/src/main/java/dev/brighten/ac/utils/wrapper/Wrapper.java @@ -27,4 +27,6 @@ public abstract class Wrapper { public abstract float getFriction(Material material); public abstract Material getType(World world, double x, double y, double z); + + public abstract boolean isCollidable(Material material); } diff --git a/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_18R3.java b/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_18R3.java index 6a87c78..48d30e8 100644 --- a/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_18R3.java +++ b/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_18R3.java @@ -1,6 +1,7 @@ package dev.brighten.ac.utils.wrapper.impl; import dev.brighten.ac.utils.wrapper.Wrapper; +import net.minecraft.server.v1_8_R3.Block; import net.minecraft.server.v1_8_R3.BlockPosition; import org.bukkit.Material; import org.bukkit.World; @@ -15,7 +16,13 @@ public class Wrapper_18R3 extends Wrapper { @Override public Material getType(World world, double x, double y, double z) { - BlockPosition blockPos = new BlockPosition(x, y, z); + final BlockPosition blockPos = new BlockPosition(x, y, z); return CraftMagicNumbers.getMaterial(((CraftWorld)world).getHandle().getType(blockPos).getBlock()); } + + @Override + public boolean isCollidable(Material material) { + final Block block = CraftMagicNumbers.getBlock(material); + return block.a(block.getBlockData(), false); + } } diff --git a/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_Reflection.java b/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_Reflection.java index 78b3934..adf5d41 100644 --- a/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_Reflection.java +++ b/src/main/java/dev/brighten/ac/utils/wrapper/impl/Wrapper_Reflection.java @@ -26,4 +26,9 @@ public class Wrapper_Reflection extends Wrapper { public Material getType(World world, double x, double y, double z) { return BlockUtils.getBlockAsync(new Location(world, x, y, z)).map(Block::getType).orElse(Material.AIR); } + + @Override + public boolean isCollidable(Material material) { + return false; + } }