9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-26 10:29:13 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0171-Asynchronous-locator.patch
Dreeam 9a4efaa230 Drop patch that causes performance regression
Originally vanilla logic is to use stream, and Mojang switched it to Guava's Collections2
since 1.21.4. It is much faster than using stream or manually adding to a new ArrayList.
Manually adding to a new ArrayList requires allocating a new object array. However, the Collections2
lazy handles filter condition on iteration, so much better.
2025-08-04 19:25:56 +08:00

243 lines
13 KiB
Diff

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<BlockPos, Holder<Structure>> 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<Boolean> 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<Boolean> 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<? extends EyeOfEnder> 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;