diff --git a/leaf-api/paper-patches/features/0010-Async-structure-locate-api.patch b/leaf-api/paper-patches/features/0010-Async-structure-locate-api.patch new file mode 100644 index 00000000..2d8985be --- /dev/null +++ b/leaf-api/paper-patches/features/0010-Async-structure-locate-api.patch @@ -0,0 +1,75 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Mon, 1 Nov 2077 00:00:00 +0800 +Subject: [PATCH] Async structure locate api + +This patch depends on Asynchronous locator patch. + +Added some asynchronous structure locate methods in World, +requires async-locator to be enabled in Leaf config, or else it will fall back to sync methods. + +diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java +index 3af8eb8064aeafa3606fed23e7ca2bc74c194726..2d314d7f75f320384c20c97f60c0c9611b890316 100644 +--- a/src/main/java/org/bukkit/World.java ++++ b/src/main/java/org/bukkit/World.java +@@ -4047,6 +4047,60 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + @Nullable + StructureSearchResult locateNearestStructure(@NotNull Location origin, @NotNull Structure structure, int radius, boolean findUnexplored); + ++ // Leaf start - Async structure locate api ++ /** ++ * Find the closest nearby structure of a given {@link StructureType} asynchronously. ++ *

++ * The {@code radius} is not a rigid square radius. Each structure may alter ++ * how many chunks to check for each iteration. Do not assume that only a ++ * radius x radius chunk area will be checked. For example, ++ * {@link StructureType#WOODLAND_MANSION} can potentially check up to 20,000 ++ * blocks away (or more) regardless of the radius used. ++ *

++ * This will not load or generate chunks. ++ *

++ * The difference between searching for a {@link StructureType} and a ++ * {@link Structure} is, that a {@link StructureType} can refer to multiple ++ * {@link Structure Structures} while searching for a {@link Structure} ++ * while only search for the given {@link Structure}. ++ * ++ * @param origin where to start looking for a structure ++ * @param structureType the type of structure to find ++ * @param radius the radius, in chunks, around which to search ++ * @param findUnexplored true to only find unexplored structures ++ * @param afterComplete the action to perform once the search is complete. ++ * @see #locateNearestStructureAsync(Location, Structure, int, boolean, Consumer) ++ */ ++ @org.jetbrains.annotations.ApiStatus.Experimental ++ void locateNearestStructureAsync(@NotNull Location origin, @NotNull StructureType structureType, int radius, boolean findUnexplored, @NotNull Consumer<@Nullable StructureSearchResult> afterComplete); ++ ++ /** ++ * Find the closest nearby structure of a given {@link Structure} asynchronously. ++ *

++ * The {@code radius} is not a rigid square radius. Each structure may alter ++ * how many chunks to check for each iteration. Do not assume that only a ++ * radius x radius chunk area will be checked. For example, ++ * {@link Structure#MANSION} can potentially check up to 20,000 blocks away ++ * (or more) regardless of the radius used. ++ *

++ * This will not load or generate chunks. ++ *

++ * The difference between searching for a {@link StructureType} and a ++ * {@link Structure} is, that a {@link StructureType} can refer to multiple ++ * {@link Structure Structures} while searching for a {@link Structure} ++ * while only search for the given {@link Structure}. ++ * ++ * @param origin where to start looking for a structure ++ * @param structure the structure to find ++ * @param radius the radius, in chunks, around which to search ++ * @param findUnexplored true to only find unexplored structures ++ * @param afterComplete the action to perform on server thread once the search is complete. ++ * @see #locateNearestStructureAsync(Location, StructureType, int, boolean, Consumer) ++ */ ++ @org.jetbrains.annotations.ApiStatus.Experimental ++ void locateNearestStructureAsync(@NotNull Location origin, @NotNull Structure structure, int radius, boolean findUnexplored, @NotNull Consumer<@Nullable StructureSearchResult> afterComplete); ++ // Leaf end - Async structure locate api ++ + // Paper start + /** + * Locates the nearest biome based on an origin, biome type, and radius to search. diff --git a/leaf-server/paper-patches/features/0028-Async-structure-locate-api.patch b/leaf-server/paper-patches/features/0028-Async-structure-locate-api.patch new file mode 100644 index 00000000..6c3f8b12 --- /dev/null +++ b/leaf-server/paper-patches/features/0028-Async-structure-locate-api.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> +Date: Mon, 1 Nov 2077 00:00:00 +0800 +Subject: [PATCH] Async structure locate api + +This patch depends on Asynchronous locator patch. + +Added some asynchronous structure locate methods in World, +requires async-locator to be enabled in Leaf config, or else it will fall back to sync methods. + +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index ba5797e9e518d7a1054bad0c7a1fb10b9eaf32bd..5d3c7a131c6becbf0c95e5c7bd8b4e727a102b24 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -2298,6 +2298,45 @@ public class CraftWorld extends CraftRegionAccessor implements World { + return new CraftStructureSearchResult(CraftStructure.minecraftToBukkit(found.getSecond().value()), CraftLocation.toBukkit(found.getFirst(), this)); + } + ++ // Leaf start - Async structure locate api ++ @Override ++ public void locateNearestStructureAsync(Location origin, StructureType structureType, int radius, boolean findUnexplored, Consumer afterComplete) { ++ List structures = new ArrayList<>(); ++ for (Structure structure : RegistryAccess.registryAccess().getRegistry(RegistryKey.STRUCTURE)) { ++ if (structure.getStructureType() == structureType) { ++ structures.add(structure); ++ } ++ } ++ ++ this.locateNearestStructureAsync(origin, structures, radius, findUnexplored, afterComplete); ++ } ++ ++ @Override ++ public void locateNearestStructureAsync(Location origin, Structure structure, int radius, boolean findUnexplored, Consumer afterComplete) { ++ this.locateNearestStructureAsync(origin, List.of(structure), radius, findUnexplored, afterComplete); ++ } ++ ++ public void locateNearestStructureAsync(Location origin, List structures, int radius, boolean findUnexplored, Consumer<@Nullable StructureSearchResult> afterComplete) { ++ if (!org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) afterComplete.accept(locateNearestStructure(origin, structures, radius, findUnexplored)); ++ BlockPos originPos = BlockPos.containing(origin.getX(), origin.getY(), origin.getZ()); ++ List> holders = new ArrayList<>(); ++ ++ for (Structure structure : structures) { ++ holders.add(Holder.direct(CraftStructure.bukkitToMinecraft(structure))); ++ } ++ ++ org.dreeam.leaf.async.locate.AsyncLocator.locate( ++ this.getHandle(), HolderSet.direct(holders), originPos, radius, findUnexplored ++ ).thenOnServerThread(found -> { ++ if (found == null) { ++ afterComplete.accept(null); ++ return; ++ } ++ afterComplete.accept(new CraftStructureSearchResult(CraftStructure.minecraftToBukkit(found.getSecond().value()), CraftLocation.toBukkit(found.getFirst(), this))); ++ }); ++ } ++ // Leaf end - Async structure locate api ++ + // Paper start + @Override + public double getCoordinateScale() {