From c9a98fc231bb8fda11ab284782ac778db9ac60b6 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Fri, 2 Aug 2024 17:06:49 +0200 Subject: [PATCH 01/14] Attempt 1 --- .../tasks/detection/DetectionTask.java | 50 +++++++++++++------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 30efd8031..2ab90af16 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -39,6 +39,8 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.data.Directional; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,7 +50,9 @@ import java.util.Collections; import java.util.Comparator; import java.util.Deque; +import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; @@ -339,6 +343,8 @@ private DetectAction(ConcurrentLinkedQueue currentFrontier, C @Override public void run() { MovecraftLocation probe; + LinkedList directionalList = new LinkedList<>(); + while((probe = currentFrontier.poll()) != null) { visitedMaterials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); if(!ALLOWED_BLOCK_VALIDATOR.validate(probe, type, movecraftWorld, player).isSucess()) @@ -350,22 +356,38 @@ public void run() { } var result = chain.validate(probe, type, movecraftWorld, player); - if(result.isSucess()) { - legal.add(probe); - if(Tags.FLUID.contains(movecraftWorld.getMaterial(probe))) - fluid.add(probe); - - size.increment(); - materials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); - for(MovecraftLocation shift : SHIFTS) { - var shifted = probe.add(shift); - if(visited.add(shifted)) - nextFrontier.add(shifted); - } - } - else { + if (!result.isSucess()) { illegal.add(probe); audience.sendMessage(Component.text(result.getMessage())); + return; + } + + Block b = probe.toBukkit(world).getBlock(); + boolean blockFacingCraft = true; + + if (b instanceof Directional directional) { + Block relativeBlock = b.getRelative(directional.getFacing()); + MovecraftLocation relativeLoc = new MovecraftLocation(relativeBlock.getX(), relativeBlock.getY(), relativeBlock.getZ()); + + if (!legal.contains(relativeLoc)) { + blockFacingCraft = false; // Invalidate block if it's not facing the craft + } + } + + if (!blockFacingCraft) { + continue; + } + + legal.add(probe); + if (Tags.FLUID.contains(movecraftWorld.getMaterial(probe))) + fluid.add(probe); + + size.increment(); + materials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + for (MovecraftLocation shift : SHIFTS) { + var shifted = probe.add(shift); + if (visited.add(shifted)) + nextFrontier.add(shifted); } } } From 380ca48a0c901b35e7a7d9a0278eba3b10613add Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sat, 3 Aug 2024 19:13:49 +0200 Subject: [PATCH 02/14] Attempt 5 --- .../tasks/detection/DetectionTask.java | 36 ++++++++++++++----- .../movecraft/MovecraftLocation.java | 5 +++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 2ab90af16..1d436a673 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -40,7 +40,10 @@ import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; +import org.bukkit.block.data.FaceAttachable; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -308,7 +311,7 @@ private void frontier() { ConcurrentLinkedQueue nextFrontier = new ConcurrentLinkedQueue<>(); currentFrontier.add(startLocation); currentFrontier.addAll(Arrays.stream(SHIFTS).map(startLocation::add).collect(Collectors.toList())); - visited.addAll(currentFrontier); + //visited.addAll(currentFrontier); int threads = Runtime.getRuntime().availableProcessors(); while(!currentFrontier.isEmpty() && size.intValue() < type.getIntProperty(CraftType.MAX_SIZE) + threads) { List> tasks = new ArrayList<>(); @@ -343,9 +346,11 @@ private DetectAction(ConcurrentLinkedQueue currentFrontier, C @Override public void run() { MovecraftLocation probe; - LinkedList directionalList = new LinkedList<>(); while((probe = currentFrontier.poll()) != null) { + if(!visited.add(probe)) + continue; + visitedMaterials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); if(!ALLOWED_BLOCK_VALIDATOR.validate(probe, type, movecraftWorld, player).isSucess()) continue; @@ -362,19 +367,27 @@ public void run() { return; } - Block b = probe.toBukkit(world).getBlock(); + BlockData bd = movecraftWorld.getData(probe); boolean blockFacingCraft = true; - if (b instanceof Directional directional) { - Block relativeBlock = b.getRelative(directional.getFacing()); - MovecraftLocation relativeLoc = new MovecraftLocation(relativeBlock.getX(), relativeBlock.getY(), relativeBlock.getZ()); + if (bd instanceof FaceAttachable attachable) { + FaceAttachable.AttachedFace attachedFace = attachable.getAttachedFace(); + BlockFace facing = toBlockFace(attachedFace, bd); + MovecraftLocation relativeLoc = probe.getRelative(facing); + + Bukkit.getLogger().info("[ATT] Type: " + bd.getMaterial() + " Loc: " + probe + " Facing: " + facing + " ATFace: " + attachedFace); + Bukkit.getLogger().info("[ATT] Relative: " + movecraftWorld.getMaterial(relativeLoc) + " Loc: " + relativeLoc); if (!legal.contains(relativeLoc)) { + Bukkit.getLogger().info("No legal"); blockFacingCraft = false; // Invalidate block if it's not facing the craft + } else { + Bukkit.getLogger().info("Yes legal"); } } if (!blockFacingCraft) { + Bukkit.getLogger().info("Skipped"); continue; } @@ -386,10 +399,17 @@ public void run() { materials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); for (MovecraftLocation shift : SHIFTS) { var shifted = probe.add(shift); - if (visited.add(shifted)) - nextFrontier.add(shifted); + nextFrontier.add(shifted); } } } + + private BlockFace toBlockFace(FaceAttachable.AttachedFace attachedFace, BlockData bd) { + return switch (attachedFace) { + case FLOOR -> BlockFace.DOWN; + case WALL -> ((Directional) bd).getFacing().getOppositeFace(); + case CEILING -> BlockFace.UP; + }; + } } } diff --git a/api/src/main/java/net/countercraft/movecraft/MovecraftLocation.java b/api/src/main/java/net/countercraft/movecraft/MovecraftLocation.java index 945bbf771..1636dec68 100644 --- a/api/src/main/java/net/countercraft/movecraft/MovecraftLocation.java +++ b/api/src/main/java/net/countercraft/movecraft/MovecraftLocation.java @@ -20,6 +20,7 @@ import com.google.common.primitives.UnsignedInteger; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.block.BlockFace; import org.jetbrains.annotations.NotNull; import static net.countercraft.movecraft.util.BitMath.mask; @@ -154,4 +155,8 @@ public int compareTo(@NotNull MovecraftLocation other) { } return 0; } + + public MovecraftLocation getRelative(BlockFace facing) { + return this.translate(facing.getModX(), facing.getModY(), facing.getModZ()); + } } From ccf16c74ebd444eda0020f89c4ffb0f20e34e0d5 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sat, 3 Aug 2024 20:24:53 +0200 Subject: [PATCH 03/14] Solved! (incomeplete) Needs a block whitelist ty <3 ohnoey --- .../tasks/detection/DetectionTask.java | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 1d436a673..9232835a3 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -39,7 +39,6 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; @@ -53,9 +52,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Deque; -import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; @@ -348,25 +345,6 @@ public void run() { MovecraftLocation probe; while((probe = currentFrontier.poll()) != null) { - if(!visited.add(probe)) - continue; - - visitedMaterials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); - if(!ALLOWED_BLOCK_VALIDATOR.validate(probe, type, movecraftWorld, player).isSucess()) - continue; - - DetectionPredicate chain = FORBIDDEN_BLOCK_VALIDATOR; - for(var validator : VALIDATORS) { - chain = chain.and(validator); - } - var result = chain.validate(probe, type, movecraftWorld, player); - - if (!result.isSucess()) { - illegal.add(probe); - audience.sendMessage(Component.text(result.getMessage())); - return; - } - BlockData bd = movecraftWorld.getData(probe); boolean blockFacingCraft = true; @@ -378,6 +356,19 @@ public void run() { Bukkit.getLogger().info("[ATT] Type: " + bd.getMaterial() + " Loc: " + probe + " Facing: " + facing + " ATFace: " + attachedFace); Bukkit.getLogger().info("[ATT] Relative: " + movecraftWorld.getMaterial(relativeLoc) + " Loc: " + relativeLoc); + if (!legal.contains(relativeLoc)) { + Bukkit.getLogger().info("No legal"); + blockFacingCraft = false; // Invalidate block if it's not facing the craft + } else { + Bukkit.getLogger().info("Yes legal"); + } + } else if (bd instanceof Directional directional) { + BlockFace facing = directional.getFacing().getOppositeFace(); + MovecraftLocation relativeLoc = probe.getRelative(facing); + + Bukkit.getLogger().info("[ATT] Type: " + bd.getMaterial() + " Loc: " + probe + " Facing: " + facing + " ATFace: " + facing); + Bukkit.getLogger().info("[ATT] Relative: " + movecraftWorld.getMaterial(relativeLoc) + " Loc: " + relativeLoc); + if (!legal.contains(relativeLoc)) { Bukkit.getLogger().info("No legal"); blockFacingCraft = false; // Invalidate block if it's not facing the craft @@ -391,6 +382,25 @@ public void run() { continue; } + if(!visited.add(probe)) + continue; + + visitedMaterials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + if(!ALLOWED_BLOCK_VALIDATOR.validate(probe, type, movecraftWorld, player).isSucess()) + continue; + + DetectionPredicate chain = FORBIDDEN_BLOCK_VALIDATOR; + for(var validator : VALIDATORS) { + chain = chain.and(validator); + } + var result = chain.validate(probe, type, movecraftWorld, player); + + if (!result.isSucess()) { + illegal.add(probe); + audience.sendMessage(Component.text(result.getMessage())); + return; + } + legal.add(probe); if (Tags.FLUID.contains(movecraftWorld.getMaterial(probe))) fluid.add(probe); From 05f81132c42a2a5d997e565c0b36898d9d90be87 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 12:29:58 +0200 Subject: [PATCH 04/14] Add Lanterns + small refactor --- .../tasks/detection/DetectionTask.java | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 9232835a3..a31d6fd11 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -43,6 +43,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; import org.bukkit.block.data.FaceAttachable; +import org.bukkit.block.data.type.Lantern; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -334,6 +335,14 @@ public String toString(){ private class DetectAction implements Runnable { private final ConcurrentLinkedQueue currentFrontier; private final ConcurrentLinkedQueue nextFrontier; + private static DetectionPredicate chain; + + static { + chain = FORBIDDEN_BLOCK_VALIDATOR; + for(var validator : VALIDATORS) { + chain = chain.and(validator); + } + } private DetectAction(ConcurrentLinkedQueue currentFrontier, ConcurrentLinkedQueue nextFrontier) { this.currentFrontier = currentFrontier; @@ -346,34 +355,30 @@ public void run() { while((probe = currentFrontier.poll()) != null) { BlockData bd = movecraftWorld.getData(probe); + Material m = bd.getMaterial(); boolean blockFacingCraft = true; - if (bd instanceof FaceAttachable attachable) { + if (m == Material.LADDER) { + BlockFace facing = ((Directional) bd).getFacing().getOppositeFace(); + MovecraftLocation relativeLoc = probe.getRelative(facing); + + if (!legal.contains(relativeLoc)) { + blockFacingCraft = false; // Invalidate block if it's not facing the craft + } + } else if (bd instanceof FaceAttachable attachable) { FaceAttachable.AttachedFace attachedFace = attachable.getAttachedFace(); BlockFace facing = toBlockFace(attachedFace, bd); MovecraftLocation relativeLoc = probe.getRelative(facing); - Bukkit.getLogger().info("[ATT] Type: " + bd.getMaterial() + " Loc: " + probe + " Facing: " + facing + " ATFace: " + attachedFace); - Bukkit.getLogger().info("[ATT] Relative: " + movecraftWorld.getMaterial(relativeLoc) + " Loc: " + relativeLoc); - if (!legal.contains(relativeLoc)) { - Bukkit.getLogger().info("No legal"); blockFacingCraft = false; // Invalidate block if it's not facing the craft - } else { - Bukkit.getLogger().info("Yes legal"); } - } else if (bd instanceof Directional directional) { - BlockFace facing = directional.getFacing().getOppositeFace(); + } else if (bd instanceof Lantern lantern) { + BlockFace facing = toBlockFace(lantern); MovecraftLocation relativeLoc = probe.getRelative(facing); - Bukkit.getLogger().info("[ATT] Type: " + bd.getMaterial() + " Loc: " + probe + " Facing: " + facing + " ATFace: " + facing); - Bukkit.getLogger().info("[ATT] Relative: " + movecraftWorld.getMaterial(relativeLoc) + " Loc: " + relativeLoc); - if (!legal.contains(relativeLoc)) { - Bukkit.getLogger().info("No legal"); blockFacingCraft = false; // Invalidate block if it's not facing the craft - } else { - Bukkit.getLogger().info("Yes legal"); } } @@ -385,14 +390,10 @@ public void run() { if(!visited.add(probe)) continue; - visitedMaterials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + visitedMaterials.computeIfAbsent(m, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); if(!ALLOWED_BLOCK_VALIDATOR.validate(probe, type, movecraftWorld, player).isSucess()) continue; - DetectionPredicate chain = FORBIDDEN_BLOCK_VALIDATOR; - for(var validator : VALIDATORS) { - chain = chain.and(validator); - } var result = chain.validate(probe, type, movecraftWorld, player); if (!result.isSucess()) { @@ -402,11 +403,11 @@ public void run() { } legal.add(probe); - if (Tags.FLUID.contains(movecraftWorld.getMaterial(probe))) + if (Tags.FLUID.contains(m)) fluid.add(probe); size.increment(); - materials.computeIfAbsent(movecraftWorld.getMaterial(probe), Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + materials.computeIfAbsent(m, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); for (MovecraftLocation shift : SHIFTS) { var shifted = probe.add(shift); nextFrontier.add(shifted); @@ -421,5 +422,9 @@ private BlockFace toBlockFace(FaceAttachable.AttachedFace attachedFace, BlockDat case CEILING -> BlockFace.UP; }; } + + private BlockFace toBlockFace(Lantern hangable) { + return hangable.isHanging() ? BlockFace.UP : BlockFace.DOWN; + } } } From 9490f8b0fc866621ee98dca41e988102f2a3ca75 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 16:51:46 +0200 Subject: [PATCH 05/14] Remove commented code --- .../movecraft/processing/tasks/detection/DetectionTask.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index a31d6fd11..2d1019548 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -309,7 +309,6 @@ private void frontier() { ConcurrentLinkedQueue nextFrontier = new ConcurrentLinkedQueue<>(); currentFrontier.add(startLocation); currentFrontier.addAll(Arrays.stream(SHIFTS).map(startLocation::add).collect(Collectors.toList())); - //visited.addAll(currentFrontier); int threads = Runtime.getRuntime().availableProcessors(); while(!currentFrontier.isEmpty() && size.intValue() < type.getIntProperty(CraftType.MAX_SIZE) + threads) { List> tasks = new ArrayList<>(); From fb06836ca58b8b8209bb28e8025a5091b481cabc Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 16:53:14 +0200 Subject: [PATCH 06/14] Refactor shorthanded variables --- .../tasks/detection/DetectionTask.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 2d1019548..6f3983dcf 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -353,26 +353,26 @@ public void run() { MovecraftLocation probe; while((probe = currentFrontier.poll()) != null) { - BlockData bd = movecraftWorld.getData(probe); - Material m = bd.getMaterial(); + BlockData blockData = movecraftWorld.getData(probe); + Material material = blockData.getMaterial(); boolean blockFacingCraft = true; - if (m == Material.LADDER) { - BlockFace facing = ((Directional) bd).getFacing().getOppositeFace(); + if (material == Material.LADDER) { + BlockFace facing = ((Directional) blockData).getFacing().getOppositeFace(); MovecraftLocation relativeLoc = probe.getRelative(facing); if (!legal.contains(relativeLoc)) { blockFacingCraft = false; // Invalidate block if it's not facing the craft } - } else if (bd instanceof FaceAttachable attachable) { + } else if (blockData instanceof FaceAttachable attachable) { FaceAttachable.AttachedFace attachedFace = attachable.getAttachedFace(); - BlockFace facing = toBlockFace(attachedFace, bd); + BlockFace facing = toBlockFace(attachedFace, blockData); MovecraftLocation relativeLoc = probe.getRelative(facing); if (!legal.contains(relativeLoc)) { blockFacingCraft = false; // Invalidate block if it's not facing the craft } - } else if (bd instanceof Lantern lantern) { + } else if (blockData instanceof Lantern lantern) { BlockFace facing = toBlockFace(lantern); MovecraftLocation relativeLoc = probe.getRelative(facing); @@ -389,7 +389,7 @@ public void run() { if(!visited.add(probe)) continue; - visitedMaterials.computeIfAbsent(m, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + visitedMaterials.computeIfAbsent(material, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); if(!ALLOWED_BLOCK_VALIDATOR.validate(probe, type, movecraftWorld, player).isSucess()) continue; @@ -402,11 +402,11 @@ public void run() { } legal.add(probe); - if (Tags.FLUID.contains(m)) + if (Tags.FLUID.contains(material)) fluid.add(probe); size.increment(); - materials.computeIfAbsent(m, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + materials.computeIfAbsent(material, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); for (MovecraftLocation shift : SHIFTS) { var shifted = probe.add(shift); nextFrontier.add(shifted); From e3f61292d913372ab9f6765c31f1ad33da0941cb Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 16:54:47 +0200 Subject: [PATCH 07/14] Remove Debugging and useless variable --- .../processing/tasks/detection/DetectionTask.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 6f3983dcf..ccce09580 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -355,14 +355,13 @@ public void run() { while((probe = currentFrontier.poll()) != null) { BlockData blockData = movecraftWorld.getData(probe); Material material = blockData.getMaterial(); - boolean blockFacingCraft = true; if (material == Material.LADDER) { BlockFace facing = ((Directional) blockData).getFacing().getOppositeFace(); MovecraftLocation relativeLoc = probe.getRelative(facing); if (!legal.contains(relativeLoc)) { - blockFacingCraft = false; // Invalidate block if it's not facing the craft + continue; // Invalidate block if it's not facing the craft } } else if (blockData instanceof FaceAttachable attachable) { FaceAttachable.AttachedFace attachedFace = attachable.getAttachedFace(); @@ -370,22 +369,17 @@ public void run() { MovecraftLocation relativeLoc = probe.getRelative(facing); if (!legal.contains(relativeLoc)) { - blockFacingCraft = false; // Invalidate block if it's not facing the craft + continue; // Invalidate block if it's not facing the craft } } else if (blockData instanceof Lantern lantern) { BlockFace facing = toBlockFace(lantern); MovecraftLocation relativeLoc = probe.getRelative(facing); if (!legal.contains(relativeLoc)) { - blockFacingCraft = false; // Invalidate block if it's not facing the craft + continue; // Invalidate block if it's not facing the craft } } - if (!blockFacingCraft) { - Bukkit.getLogger().info("Skipped"); - continue; - } - if(!visited.add(probe)) continue; From d8498b27206eaf36ec1b816948e15b114bf52563 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 17:07:42 +0200 Subject: [PATCH 08/14] Undo: Revert a conditional --- .../tasks/detection/DetectionTask.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index ccce09580..76c33997b 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -389,21 +389,20 @@ public void run() { var result = chain.validate(probe, type, movecraftWorld, player); - if (!result.isSucess()) { + if (result.isSucess()) { + legal.add(probe); + if (Tags.FLUID.contains(material)) + fluid.add(probe); + + size.increment(); + materials.computeIfAbsent(material, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); + for (MovecraftLocation shift : SHIFTS) { + var shifted = probe.add(shift); + nextFrontier.add(shifted); + } + } else { illegal.add(probe); audience.sendMessage(Component.text(result.getMessage())); - return; - } - - legal.add(probe); - if (Tags.FLUID.contains(material)) - fluid.add(probe); - - size.increment(); - materials.computeIfAbsent(material, Functions.forSupplier(ConcurrentLinkedDeque::new)).add(probe); - for (MovecraftLocation shift : SHIFTS) { - var shifted = probe.add(shift); - nextFrontier.add(shifted); } } } From 1dcbab43ffe9ca81dd906fc4f492bc272e0ab19c Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 17:44:59 +0200 Subject: [PATCH 09/14] Made SupportUtils class --- .../tasks/detection/DetectionTask.java | 41 +++--------------- .../tasks/detection/SupportUtils.java | 43 +++++++++++++++++++ 2 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 76c33997b..005426405 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -41,9 +41,6 @@ import org.bukkit.World; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Directional; -import org.bukkit.block.data.FaceAttachable; -import org.bukkit.block.data.type.Lantern; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -56,6 +53,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -356,28 +354,13 @@ public void run() { BlockData blockData = movecraftWorld.getData(probe); Material material = blockData.getMaterial(); - if (material == Material.LADDER) { - BlockFace facing = ((Directional) blockData).getFacing().getOppositeFace(); + Optional blockDataOptional = SupportUtils.getSupportFace(blockData); + if (blockDataOptional.isPresent()) { + BlockFace facing = blockDataOptional.get(); MovecraftLocation relativeLoc = probe.getRelative(facing); - if (!legal.contains(relativeLoc)) { - continue; // Invalidate block if it's not facing the craft - } - } else if (blockData instanceof FaceAttachable attachable) { - FaceAttachable.AttachedFace attachedFace = attachable.getAttachedFace(); - BlockFace facing = toBlockFace(attachedFace, blockData); - MovecraftLocation relativeLoc = probe.getRelative(facing); - - if (!legal.contains(relativeLoc)) { - continue; // Invalidate block if it's not facing the craft - } - } else if (blockData instanceof Lantern lantern) { - BlockFace facing = toBlockFace(lantern); - MovecraftLocation relativeLoc = probe.getRelative(facing); - - if (!legal.contains(relativeLoc)) { - continue; // Invalidate block if it's not facing the craft - } + if (!legal.contains(relativeLoc)) + continue; } if(!visited.add(probe)) @@ -406,17 +389,5 @@ public void run() { } } } - - private BlockFace toBlockFace(FaceAttachable.AttachedFace attachedFace, BlockData bd) { - return switch (attachedFace) { - case FLOOR -> BlockFace.DOWN; - case WALL -> ((Directional) bd).getFacing().getOppositeFace(); - case CEILING -> BlockFace.UP; - }; - } - - private BlockFace toBlockFace(Lantern hangable) { - return hangable.isHanging() ? BlockFace.UP : BlockFace.DOWN; - } } } diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java new file mode 100644 index 000000000..c8fde05aa --- /dev/null +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java @@ -0,0 +1,43 @@ +package net.countercraft.movecraft.processing.tasks.detection; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.FaceAttachable; +import org.bukkit.block.data.type.Lantern; + +import java.util.Optional; + +/** + * @author Intybyte/Vaan1310 + * An util craft that uses block data to get its supporting block + */ + +public class SupportUtils { + public static Optional getSupportFace(BlockData data) { + + if (data.getMaterial() == Material.LADDER) { + BlockFace face = ((Directional) data).getFacing().getOppositeFace(); + return Optional.of(face); + } + + //This should become Hangable instead when we drop support for 1.18 + if (data instanceof Lantern lantern) + return Optional.of(lantern.isHanging() ? BlockFace.UP : BlockFace.DOWN); + + if (data instanceof FaceAttachable faceAttachable) { + //this cast should never fail as the only blocks that implement FaceAttachable + //are also directional: Switch(Lever) and Grindstone + Directional directional = (Directional) data; + + return switch (faceAttachable.getAttachedFace()) { + case FLOOR -> Optional.of(BlockFace.DOWN); + case WALL -> Optional.of(directional.getFacing().getOppositeFace()); + case CEILING -> Optional.of(BlockFace.UP); + }; + } + + return Optional.empty(); + } +} From 2ec44905fc96c5e04a9f7216475f9d7921111136 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 19:30:59 +0200 Subject: [PATCH 10/14] Adding Reminders + More robust FaceAttachable checks --- .../processing/tasks/detection/SupportUtils.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java index c8fde05aa..4e0207310 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java @@ -22,15 +22,12 @@ public static Optional getSupportFace(BlockData data) { return Optional.of(face); } - //This should become Hangable instead when we drop support for 1.18 + //TODO: Use pattern matched switch statements once we update do Java 21 + //TODO: This should become Hangable instead when we drop support for 1.18 if (data instanceof Lantern lantern) return Optional.of(lantern.isHanging() ? BlockFace.UP : BlockFace.DOWN); - if (data instanceof FaceAttachable faceAttachable) { - //this cast should never fail as the only blocks that implement FaceAttachable - //are also directional: Switch(Lever) and Grindstone - Directional directional = (Directional) data; - + if (data instanceof FaceAttachable faceAttachable && data instanceof Directional directional) { return switch (faceAttachable.getAttachedFace()) { case FLOOR -> Optional.of(BlockFace.DOWN); case WALL -> Optional.of(directional.getFacing().getOppositeFace()); From 2ddac224e5773ed5e42c26f43090ceef5c441a08 Mon Sep 17 00:00:00 2001 From: Intybyte Date: Sun, 4 Aug 2024 23:07:11 +0200 Subject: [PATCH 11/14] Add directionDependentMaterials --- .../tasks/detection/DetectionTask.java | 4 ++- .../tasks/detection/SupportUtils.java | 27 ++++++++++++------- .../movecraft/craft/type/CraftType.java | 9 +++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java index 005426405..1cf1eff8c 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/DetectionTask.java @@ -50,6 +50,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Deque; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -349,12 +350,13 @@ private DetectAction(ConcurrentLinkedQueue currentFrontier, C @Override public void run() { MovecraftLocation probe; + EnumSet directionalDependent = type.getMaterialSetProperty(CraftType.DIRECTIONAL_DEPENDENT_MATERIALS); while((probe = currentFrontier.poll()) != null) { BlockData blockData = movecraftWorld.getData(probe); Material material = blockData.getMaterial(); - Optional blockDataOptional = SupportUtils.getSupportFace(blockData); + Optional blockDataOptional = SupportUtils.getSupportFace(blockData, directionalDependent); if (blockDataOptional.isPresent()) { BlockFace facing = blockDataOptional.get(); MovecraftLocation relativeLoc = probe.getRelative(facing); diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java index 4e0207310..af2decf2e 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/processing/tasks/detection/SupportUtils.java @@ -7,6 +7,7 @@ import org.bukkit.block.data.FaceAttachable; import org.bukkit.block.data.type.Lantern; +import java.util.EnumSet; import java.util.Optional; /** @@ -15,11 +16,11 @@ */ public class SupportUtils { - public static Optional getSupportFace(BlockData data) { + public static Optional getSupportFace(BlockData data, EnumSet directionalDependent) { - if (data.getMaterial() == Material.LADDER) { - BlockFace face = ((Directional) data).getFacing().getOppositeFace(); - return Optional.of(face); + Material material = data.getMaterial(); + if (!directionalDependent.contains(material)) { + return Optional.empty(); } //TODO: Use pattern matched switch statements once we update do Java 21 @@ -27,12 +28,18 @@ public static Optional getSupportFace(BlockData data) { if (data instanceof Lantern lantern) return Optional.of(lantern.isHanging() ? BlockFace.UP : BlockFace.DOWN); - if (data instanceof FaceAttachable faceAttachable && data instanceof Directional directional) { - return switch (faceAttachable.getAttachedFace()) { - case FLOOR -> Optional.of(BlockFace.DOWN); - case WALL -> Optional.of(directional.getFacing().getOppositeFace()); - case CEILING -> Optional.of(BlockFace.UP); - }; + if (data instanceof Directional directional) { + BlockFace normalCase = directional.getFacing().getOppositeFace(); + + if (data instanceof FaceAttachable faceAttachable) { + return switch (faceAttachable.getAttachedFace()) { + case FLOOR -> Optional.of(BlockFace.DOWN); + case WALL -> Optional.of(normalCase); + case CEILING -> Optional.of(BlockFace.UP); + }; + } + + return Optional.of(normalCase); } return Optional.empty(); diff --git a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java index 2ed26e40d..a12649136 100644 --- a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java +++ b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java @@ -53,6 +53,7 @@ import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -189,6 +190,7 @@ final public class CraftType { public static final NamespacedKey CRUISE_ON_PILOT_LIFETIME = buildKey("cruise_on_pilot_lifetime"); public static final NamespacedKey EXPLOSION_ARMING_TIME = buildKey("explosion_arming_time"); + public static final NamespacedKey DIRECTIONAL_DEPENDENT_MATERIALS = buildKey("directional_dependent_materials"); //endregion @Contract("_ -> new") @@ -391,6 +393,13 @@ public static void registerTypeValidator(Predicate validator, String /* Optional properties */ registerProperty(new RequiredBlockProperty("flyblocks", FLY_BLOCKS, type -> new HashSet<>())); registerProperty(new RequiredBlockProperty("detectionblocks", DETECTION_BLOCKS, type -> new HashSet<>())); + registerProperty(new MaterialSetProperty("directionDependentMaterials", DIRECTIONAL_DEPENDENT_MATERIALS, type -> { + var set = EnumSet.of(Material.LADDER, Material.TORCH, Material.LEVER, Material.GRINDSTONE, Material.LANTERN); + //add all Signs (maybe there is a better way to do it?) + Arrays.stream(Material.values()).filter(mat -> mat.name().endsWith("_SIGN")).forEach(set::add); + return set; + })); + registerProperty(new ObjectPropertyImpl("forbiddenSignStrings", FORBIDDEN_SIGN_STRINGS, (data, type, fileKey, namespacedKey) -> data.getStringListOrEmpty(fileKey).stream().map( String::toLowerCase).collect(Collectors.toSet()), From 3b4dfd92cce0f75eb4ed07886e6b87c3308f5c1b Mon Sep 17 00:00:00 2001 From: Intybyte Date: Mon, 5 Aug 2024 08:49:16 +0200 Subject: [PATCH 12/14] Fix Signs (only get wall signs as they are directional) --- .../java/net/countercraft/movecraft/craft/type/CraftType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java index a12649136..29da761e6 100644 --- a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java +++ b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java @@ -396,7 +396,7 @@ public static void registerTypeValidator(Predicate validator, String registerProperty(new MaterialSetProperty("directionDependentMaterials", DIRECTIONAL_DEPENDENT_MATERIALS, type -> { var set = EnumSet.of(Material.LADDER, Material.TORCH, Material.LEVER, Material.GRINDSTONE, Material.LANTERN); //add all Signs (maybe there is a better way to do it?) - Arrays.stream(Material.values()).filter(mat -> mat.name().endsWith("_SIGN")).forEach(set::add); + Arrays.stream(Material.values()).filter(mat -> mat.name().endsWith("WALL_SIGN")).forEach(set::add); return set; })); From 54262f32211619b616d111ffd2bdcbc90aa24c69 Mon Sep 17 00:00:00 2001 From: xF3d Date: Wed, 14 Aug 2024 13:43:27 +0200 Subject: [PATCH 13/14] Use `Tag.WALL_SIGNS` instead --- .../net/countercraft/movecraft/craft/type/CraftType.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java index 29da761e6..f5a8dee42 100644 --- a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java +++ b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java @@ -43,10 +43,7 @@ import net.countercraft.movecraft.util.Tags; import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.World; +import org.bukkit.*; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -396,7 +393,7 @@ public static void registerTypeValidator(Predicate validator, String registerProperty(new MaterialSetProperty("directionDependentMaterials", DIRECTIONAL_DEPENDENT_MATERIALS, type -> { var set = EnumSet.of(Material.LADDER, Material.TORCH, Material.LEVER, Material.GRINDSTONE, Material.LANTERN); //add all Signs (maybe there is a better way to do it?) - Arrays.stream(Material.values()).filter(mat -> mat.name().endsWith("WALL_SIGN")).forEach(set::add); + set.addAll(Tag.WALL_SIGNS.getValues()); return set; })); From 81a6feae35c2e4a7859ff884e83c6a86fcb2eca7 Mon Sep 17 00:00:00 2001 From: xF3d Date: Wed, 14 Aug 2024 13:49:40 +0200 Subject: [PATCH 14/14] Created Tags.WALL_TORCHES and used that instead --- .../net/countercraft/movecraft/craft/type/CraftType.java | 5 ++--- api/src/main/java/net/countercraft/movecraft/util/Tags.java | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java index f5a8dee42..1e420adc0 100644 --- a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java +++ b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java @@ -50,7 +50,6 @@ import java.io.File; import java.util.ArrayList; -import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -391,9 +390,9 @@ public static void registerTypeValidator(Predicate validator, String registerProperty(new RequiredBlockProperty("flyblocks", FLY_BLOCKS, type -> new HashSet<>())); registerProperty(new RequiredBlockProperty("detectionblocks", DETECTION_BLOCKS, type -> new HashSet<>())); registerProperty(new MaterialSetProperty("directionDependentMaterials", DIRECTIONAL_DEPENDENT_MATERIALS, type -> { - var set = EnumSet.of(Material.LADDER, Material.TORCH, Material.LEVER, Material.GRINDSTONE, Material.LANTERN); - //add all Signs (maybe there is a better way to do it?) + var set = EnumSet.of(Material.LADDER, Material.LEVER, Material.GRINDSTONE, Material.LANTERN); set.addAll(Tag.WALL_SIGNS.getValues()); + set.addAll(Tags.WALL_TORCHES); return set; })); diff --git a/api/src/main/java/net/countercraft/movecraft/util/Tags.java b/api/src/main/java/net/countercraft/movecraft/util/Tags.java index 6e8a03257..ec91b5384 100644 --- a/api/src/main/java/net/countercraft/movecraft/util/Tags.java +++ b/api/src/main/java/net/countercraft/movecraft/util/Tags.java @@ -4,14 +4,11 @@ import org.bukkit.Keyed; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.EnumSet; -import java.util.HashSet; -import java.util.Set; public class Tags { public static final EnumSet WATER = EnumSet.of(Material.WATER, Material.BUBBLE_COLUMN); @@ -22,6 +19,7 @@ public class Tags { public static final EnumSet FRAGILE_MATERIALS = EnumSet.noneOf(Material.class); public static final EnumSet FALL_THROUGH_BLOCKS = EnumSet.noneOf(Material.class); public static final EnumSet BUCKETS = EnumSet.of(Material.LAVA_BUCKET, Material.WATER_BUCKET, Material.MILK_BUCKET, Material.COD_BUCKET, Material.PUFFERFISH_BUCKET, Material.SALMON_BUCKET, Material.TROPICAL_FISH_BUCKET); + public static final EnumSet WALL_TORCHES = EnumSet.of(Material.WALL_TORCH, Material.SOUL_WALL_TORCH, Material.REDSTONE_WALL_TORCH); static { FRAGILE_MATERIALS.add(Material.PISTON_HEAD);