mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-26 10:29:13 +00:00
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.
243 lines
13 KiB
Diff
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;
|