From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Date: Wed, 23 Oct 2024 23:54:00 +0800 Subject: [PATCH] Asynchronous locator Original license: MIT Original project: https://github.com/thebrightspark/AsyncLocator diff --git a/net/minecraft/server/commands/LocateCommand.java b/net/minecraft/server/commands/LocateCommand.java index a734b2597c3491db35d9660e169f8e8b6320900b..5274f09b0abf148aea1c0baa39edbfdac1acc4f5 100644 --- a/net/minecraft/server/commands/LocateCommand.java +++ b/net/minecraft/server/commands/LocateCommand.java @@ -106,6 +106,34 @@ public class LocateCommand { BlockPos blockPos = BlockPos.containing(source.getPosition()); ServerLevel level = source.getLevel(); Stopwatch stopwatch = Stopwatch.createStarted(Util.TICKER); + // Leaf start - Asynchronous locator + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) { + BlockPos originPos = BlockPos.containing(source.getPosition()); + org.dreeam.leaf.async.locate.AsyncLocator.locate(source.getLevel(), holderSet, originPos, 100, false) + .thenOnServerThread(pair -> { + stopwatch.stop(); + if (pair != null) { + showLocateResult( + source, + structure, + originPos, + pair, + "commands.locate.structure.success", + false, + stopwatch.elapsed() + ); + } else { + source.sendFailure( + Component.literal( + ERROR_STRUCTURE_NOT_FOUND.create(structure.asPrintable()).getMessage() + ) + ); + } + }); + + return 0; + } + // Leaf end - Asynchronous locator Pair> pair = level.getChunkSource().getGenerator().findNearestMapStructure(level, holderSet, blockPos, 100, false); stopwatch.stop(); if (pair == null) { diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java index eaaa66c4d86d4ebda0acf8f1dbe8ecb55aa28285..8f41326fda8c5f9f6926038508be6c6529b051bc 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -852,14 +852,25 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @Override public boolean pollTask() { + // Leaf start - Async Locator // Paper start - rewrite chunk system - final ServerChunkCache serverChunkCache = ServerChunkCache.this; - if (serverChunkCache.runDistanceManagerUpdates()) { - return true; + java.util.function.Supplier supplier = () -> { + final ServerChunkCache serverChunkCache = ServerChunkCache.this; + if (serverChunkCache.runDistanceManagerUpdates()) { + return true; + } else { + return super.pollTask() | ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) serverChunkCache.level).moonrise$getChunkTaskScheduler().executeMainThreadTask(); + } + }; + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && Thread.currentThread() instanceof org.dreeam.leaf.async.locate.AsyncLocator.AsyncLocatorThread) { + return MinecraftServer.getServer().scheduleWithResult((java.util.concurrent.CompletableFuture future) -> { + future.complete(supplier.get()); + }).join(); } else { - return super.pollTask() | ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)serverChunkCache.level).moonrise$getChunkTaskScheduler().executeMainThreadTask(); + return supplier.get(); } // Paper end - rewrite chunk system + // Leaf end - Async Locator } } } diff --git a/net/minecraft/world/entity/animal/Dolphin.java b/net/minecraft/world/entity/animal/Dolphin.java index 23696a5e2871ea07f34d4b4f6a20e2896ac3f5bd..c4fda92e078c9ba745b2548ecaaffffff97fb0fd 100644 --- a/net/minecraft/world/entity/animal/Dolphin.java +++ b/net/minecraft/world/entity/animal/Dolphin.java @@ -487,6 +487,10 @@ public class Dolphin extends AgeableWaterCreature { static class DolphinSwimToTreasureGoal extends Goal { private final Dolphin dolphin; private boolean stuck; + // Leaf start - Asynchronous locator + @Nullable + private org.dreeam.leaf.async.locate.AsyncLocator.LocateTask asyncLocator$locateTask; + // Leaf end - Asynchronous locator DolphinSwimToTreasureGoal(Dolphin dolphin) { this.dolphin = dolphin; @@ -506,6 +510,11 @@ public class Dolphin extends AgeableWaterCreature { @Override public boolean canContinueToUse() { + // Leaf start - Asynchronous locator + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) { + return true; + } + // Leaf end - Asynchronous locator BlockPos blockPos = this.dolphin.treasurePos; return blockPos != null && !BlockPos.containing(blockPos.getX(), this.dolphin.getY(), blockPos.getZ()).closerToCenterThan(this.dolphin.position(), 4.0) @@ -520,6 +529,22 @@ public class Dolphin extends AgeableWaterCreature { this.stuck = false; this.dolphin.getNavigation().stop(); BlockPos blockPos = this.dolphin.blockPosition(); + // Leaf start - Asynchronous locator + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) { + asyncLocator$locateTask = org.dreeam.leaf.async.locate.AsyncLocator.locate(serverLevel, StructureTags.DOLPHIN_LOCATED, blockPos, 50, false) + .thenOnServerThread(pos -> { + asyncLocator$locateTask = null; + if (pos != null) { + this.dolphin.treasurePos = pos; + serverLevel.broadcastEntityEvent(this.dolphin, (byte) 38); + } else { + this.stuck = true; + } + }); + + return; + } + // Leaf end - Asynchronous locator BlockPos blockPos1 = serverLevel.findNearestMapStructure(StructureTags.DOLPHIN_LOCATED, blockPos, 50, false); if (blockPos1 != null) { this.dolphin.treasurePos = blockPos1; @@ -532,6 +557,12 @@ public class Dolphin extends AgeableWaterCreature { @Override public void stop() { + // Leaf start - Asynchronous locator + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) { + this.asyncLocator$locateTask.cancel(); + this.asyncLocator$locateTask = null; + } + // Leaf end - Asynchronous locator BlockPos blockPos = this.dolphin.treasurePos; if (blockPos == null || BlockPos.containing(blockPos.getX(), this.dolphin.getY(), blockPos.getZ()).closerToCenterThan(this.dolphin.position(), 4.0) @@ -542,6 +573,11 @@ public class Dolphin extends AgeableWaterCreature { @Override public void tick() { + // Leaf start - Asynchronous locator + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTask != null) { + return; + } + // Leaf end - Asynchronous locator if (this.dolphin.treasurePos != null) { Level level = this.dolphin.level(); if (this.dolphin.closeToNextPos() || this.dolphin.getNavigation().isDone()) { diff --git a/net/minecraft/world/entity/projectile/EyeOfEnder.java b/net/minecraft/world/entity/projectile/EyeOfEnder.java index 2bb3c5018be0c669da4c28a34ce2f2e124547691..2c34e956e8a3263bb05ae2810a8578696f739263 100644 --- a/net/minecraft/world/entity/projectile/EyeOfEnder.java +++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java @@ -28,6 +28,7 @@ public class EyeOfEnder extends Entity implements ItemSupplier { public Vec3 target; public int life; public boolean surviveAfterDeath; + public boolean asyncLocator$locateTaskOngoing = false; // Leaf - Asynchronous locator public EyeOfEnder(EntityType entityType, Level level) { super(entityType, level); @@ -95,6 +96,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier { @Override public void tick() { super.tick(); + // Leaf start - Asynchronous locator + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled && this.asyncLocator$locateTaskOngoing) { + return; + } + // Leaf end - Asynchronous locator Vec3 vec3 = this.position().add(this.getDeltaMovement()); if (!this.level().isClientSide() && this.target != null) { this.setDeltaMovement(updateDeltaMovement(this.getDeltaMovement(), vec3, this.target)); diff --git a/net/minecraft/world/item/EnderEyeItem.java b/net/minecraft/world/item/EnderEyeItem.java index 51e0985bde9cf6ac2f4264d21edec3d1623a2d0d..ca2b493e4032208311c857db799632ac3d3ab077 100644 --- a/net/minecraft/world/item/EnderEyeItem.java +++ b/net/minecraft/world/item/EnderEyeItem.java @@ -106,14 +106,46 @@ public class EnderEyeItem extends Item { } else { player.startUsingItem(hand); if (level instanceof ServerLevel serverLevel) { - BlockPos blockPos = serverLevel.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, player.blockPosition(), 100, false); + // Leaf start - Asynchronous locator + BlockPos blockPos; + if (org.dreeam.leaf.config.modules.async.AsyncLocator.enabled) { + blockPos = BlockPos.ZERO; + } else { + blockPos = serverLevel.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, player.blockPosition(), 100, false); + } + // Leaf end - Asynchronous locator if (blockPos == null) { return InteractionResult.CONSUME; } EyeOfEnder eyeOfEnder = new EyeOfEnder(level, player.getX(), player.getY(0.5), player.getZ()); + + // Leaf start - Asynchronous locator + final boolean isAsyncLocatorEnabled = org.dreeam.leaf.config.modules.async.AsyncLocator.enabled; + + if (isAsyncLocatorEnabled) { + eyeOfEnder.asyncLocator$locateTaskOngoing = true; + org.dreeam.leaf.async.locate.AsyncLocator.locate( + serverLevel, + StructureTags.EYE_OF_ENDER_LOCATED, + player.blockPosition(), + 100, + false + ).thenOnServerThread(pos -> { + eyeOfEnder.asyncLocator$locateTaskOngoing = false; + if (pos != null) { + eyeOfEnder.signalTo(Vec3.atLowerCornerOf(pos)); + CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer) player, pos); + player.awardStat(Stats.ITEM_USED.get(this)); + } else { + // Set the entity's life to long enough that it dies + eyeOfEnder.life = Integer.MAX_VALUE - 100; + } + }); + } + // Leaf end - Asynchronous locator eyeOfEnder.setItem(itemInHand); - eyeOfEnder.signalTo(Vec3.atLowerCornerOf(blockPos)); + if (!isAsyncLocatorEnabled) eyeOfEnder.signalTo(Vec3.atLowerCornerOf(blockPos)); // Leaf - Asynchronous locator level.gameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnder.position(), GameEvent.Context.of(player)); // CraftBukkit start if (!level.addFreshEntity(eyeOfEnder)) { @@ -127,7 +159,7 @@ public class EnderEyeItem extends Item { float f = Mth.lerp(level.random.nextFloat(), 0.33F, 0.5F); level.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDER_EYE_LAUNCH, SoundSource.NEUTRAL, 1.0F, f); itemInHand.consume(1, player); - player.awardStat(Stats.ITEM_USED.get(this)); + if (!isAsyncLocatorEnabled) player.awardStat(Stats.ITEM_USED.get(this)); // Leaf - Asynchronous locator } return InteractionResult.SUCCESS_SERVER;