Upstream has released updates that appears to apply and compile correctly Paper Changes: cfed00cf Fix Light Command a6ff84ad Revert Nibble patch, causing issues still f1a8eb7f Use a finalizer for light packet instead of onPacketDone 03c9bb05 Optimize NibbleArray to use pooled buffers d0a528b1 Move delayed init down later in tick, improve accuracy of startup time cc477e6a Force Plugins that use delayed tasks for init back in their place 597263fd Don't skip full player connection tick when dead e2c23475 Revert loaded entity list (#3304) fa87db6b Move another NetworkManager util into the inner class (#3303) 841c7d18 Make loaded entity list logic more consistent (#3301) 36f34f01 Updated Upstream (Bukkit/CraftBukkit) 5ca5f131 Rebuild all patches using the new rebuild pattern 1ccff6fa Add villager reputation API 5c0bfffa Speed up rebuilding patches and reduce diff f37381ea Optimize Network Manager to not need synchronization 8f9df2ed Anti Xray cleanup 878c66f1 No-Tick view distance implementation - Closes #3196 b87743c1 Stop copy-on-write operations for updating light data 97a9c972 Optimize isOutsideRange to use distance maps b4e629a2 Use distance map to optimise entity tracker / Misc Utils d80d1517 Optimize Entity Ticking to Loaded Chunks only 31d7686d Add item slot helper methods for various inventories (#3221) 75e1e3b3 Mob Goal API c7bc393a Revert "Don't flush packet queue off main thread" 1abd2bd2 Don't flush packet queue off main thread a4ed58a9 Clean up Direct Memory Region Files Fix for different Java versions 55e35019 Set cap on JDK per-thread native byte buffer cache b5101f4f Cleanup Region Files Direct Memory on close 81e655d7 Optimize Voxel Shape Merging ed9fc11f Sync position on teleportation 9c326fce Nanothing to see here 3e9fc24b Attempt to fix FastLogin maybe 932e97f3 Rename to AsyncPlayerSendSuggestionsEvent to be consistent in naming 0dd19075 AsyncSendPlayerSuggestionsEvent Brigadier Event a9e20e5f Fix being kicked in survival for block picking - Fixes #3277 4d20537e Expose game version (#3274) 85fb0015 Validate PickItem Packet and kick for invalid - Fixes #3256 5729bc71 Special case Keep Alive packets from Anti Xray a76b7740 Improved oversized chunk data packet handling a6f78170 Use Vanilla Bed Search for non players (Villagers) 68fb98b5 Fix 2 plugin specific issues with loot drop and pathfinders 6e41f7b7 Update Activation Range 2.0 with more villager controls 57dd3971 Updated Upstream (Bukkit/CraftBukkit) a6a197b1 Bump API ASM version to follow server 5ab48ad9 Fix commodore (#3264) 87e7ee7e Improve Async Login to avoid firing in middle of Entity Ticking 8ce3dd5f [CI-SKIP] Fix Mojang API Brigadier dep - THIS IS NOT A NEW BUILD 00d760a5 Fix build due to spigot changing the build timestamp process 842e040c Updated Upstream (Bukkit/CraftBukkit/Spigot) c03260a2 Add getter and setter for villager's numberOfRestocksToday (#3231) fe366fbe null check tracker for entity metadata update - Fixes #3070 fdf41b74 Implement Brigadier Mojang API e0ea2e0e Entity Activation Range 2.0! Major improvements to restoring behavior 10396d28 Fix Tracking Range mismatch on Vehicle/Passenger checks 68994c64 Add a config to turn off Optimized TickList #3145 d847d336 Improve blocking players from opening inventories while sleeping ac4f6b50 Clean up Timings and Async Chunk Configs fcf89e85 Improve mid tick chunk loading, Fix Oversleep, other improvements ab36835c Improve random ticking behaviour - Fixes #3181 a6ac47e5 Fix numerous item duplication issues and teleport issues b7402f11 Add phantom creative and insomniac controls (#3222) 75819fac Fix Potion#toItemStack swapping the extended and upgraded constructor values (#3216) cb15cfa4 Improve Async Login so pending connections dont get exposed f275e9cb Optimize Hoppers - Major Boost - Got2GoFast! 0106485c Improvements to watchdog changes 65934b1f Fix build for last commit. 5am commits are great 3f436029 Don't process watchdog until server has fully started and ticked. 938bd972 Don't fire BlockFade on worldgen threads - Fixes #3208 509a828e Fix loading spawn chunks when async chunks is off 8a91bfd2 Improvements to async login bf698865 Revert "Re-track players that dismount from other players" 82b98418 Fix some issues with async login as well another source of sync loads aa241d2b Allow multiple callbacks to schedule for Callback Executor a2064a41 Add PlayerAttackEntityCooldownResetEvent This event is called when processing a player's attack on an entity right before their attack strength cd is reset, there are no existing events that fire within this period of time so it was impossible to capture the players attack strength via API prior to this commit. f48d4299 Allow sleeping players to float eeb2f67d Fix Bed respawn deviating too far from vanilla (#3195) 68a7b9fe Move player to spawn point if spawn in unloaded world f29c7ebd Improve async login (#3189) 9fd36824 Fix Citizens Player NPC tracking issue - Fixes #3186
262 lines
11 KiB
Diff
262 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?=E3=84=97=E3=84=A0=CB=8B=20=E3=84=91=E3=84=A7=CB=8A?=
|
|
<tsao-chi@the-lingo.org>
|
|
Date: Sun, 5 Apr 2020 13:01:13 +0800
|
|
Subject: [PATCH] Asynchronous pathfinding
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
index 5aca7a9131787415fb2edba1ebec9601e8a56d3a..7a0f18a8f7d7cdeca9a45485f5b22353e726aae8 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
@@ -686,7 +686,7 @@ public abstract class EntityInsentient extends EntityLiving {
|
|
this.goalSelector.doTick();
|
|
this.world.getMethodProfiler().exit();
|
|
this.world.getMethodProfiler().enter("navigation");
|
|
- this.navigation.c();
|
|
+ this.navigation.tickAsync(); // Akarin - Async pathfinder
|
|
this.world.getMethodProfiler().exit();
|
|
this.world.getMethodProfiler().enter("mob tick");
|
|
this.mobTick();
|
|
diff --git a/src/main/java/net/minecraft/server/Navigation.java b/src/main/java/net/minecraft/server/Navigation.java
|
|
index abf450917e605972d84cb603b966feb013ae0002..4f7f40d5e7050d9b2da29c6e6efe7c5bef560d55 100644
|
|
--- a/src/main/java/net/minecraft/server/Navigation.java
|
|
+++ b/src/main/java/net/minecraft/server/Navigation.java
|
|
@@ -183,7 +183,7 @@ public class Navigation extends NavigationAbstract {
|
|
double d3 = (double) j2 + 0.5D - vec3d.z;
|
|
|
|
if (d2 * d0 + d3 * d1 >= 0.0D) {
|
|
- PathType pathtype = this.o.a(this.b, i2, j - 1, j2, this.a, l, i1, j1, true, true);
|
|
+ PathType pathtype = this.o.a(this.o.a, i2, j - 1, j2, this.a, l, i1, j1, true, true); // Akarin - use chunk cache
|
|
|
|
if (pathtype == PathType.WATER) {
|
|
return false;
|
|
diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
index dc32107ec320fa54487f24c9d68ff8e5a6dea1bb..f7ea00d6ffa2000c4d0d74b5856ba66bba165d5a 100644
|
|
--- a/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
+++ b/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
@@ -29,6 +29,15 @@ public abstract class NavigationAbstract {
|
|
private int r;
|
|
private float s;
|
|
private final Pathfinder t; public Pathfinder getPathfinder() { return this.t; } // Paper - OBFHELPER
|
|
+ // Akarin start - Async pathfinder
|
|
+ private long lastPathfindAsync;
|
|
+ private static final java.util.concurrent.ExecutorService pathfindExecutor =
|
|
+ java.util.concurrent.Executors.newSingleThreadExecutor(
|
|
+ new com.google.common.util.concurrent.ThreadFactoryBuilder()
|
|
+ .setDaemon(true)
|
|
+ .setNameFormat("StarLink Pathfinder - %d")
|
|
+ .build());
|
|
+ // Akarin end
|
|
|
|
public NavigationAbstract(EntityInsentient entityinsentient, World world) {
|
|
this.g = Vec3D.a;
|
|
@@ -78,6 +87,40 @@ public abstract class NavigationAbstract {
|
|
}
|
|
|
|
}
|
|
+ // Akarin start - Async pathfinder, copied from above with modification
|
|
+ public void doPathfindAsync() {
|
|
+ if (this.b.getTime() - this.lastPathfindAsync > 20L) {
|
|
+ if (this.q != null) {
|
|
+ this.lastPathfindAsync = this.b.getTime();
|
|
+
|
|
+ // Bake chunk cache
|
|
+ float f = (float) this.p.getValue();
|
|
+ BlockPosition blockposition = new BlockPosition(this.a);
|
|
+ int k = (int) (f + (float) 8);
|
|
+ ChunkCache cache = new ChunkCache(this.b, blockposition.b(-k, -k, -k), blockposition.b(k, k, k));
|
|
+
|
|
+ // Execute directly if we already have a path entity, or compute one
|
|
+ if (this.c != null && !this.c.b()) {
|
|
+ doTickAsync(this.c);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ pathfindExecutor.execute(() -> {
|
|
+ PathEntity result = findPathAsync(cache, java.util.Collections.singleton(this.q), this.r);
|
|
+ NavigationAbstract.this.b.getMinecraftServer().processQueue.add(() -> {
|
|
+ if (result != null && result.k() != null)
|
|
+ this.q = result.k();
|
|
+
|
|
+ NavigationAbstract.this.c = result;
|
|
+ });
|
|
+ });
|
|
+ }
|
|
+ } else {
|
|
+ // Execute directly, keep behaviour with vanilla, see the original doTick method
|
|
+ doTickAsync(this.c);
|
|
+ }
|
|
+ }
|
|
+ // Akarin end
|
|
|
|
@Nullable
|
|
public final PathEntity calculateDestination(double d0, double d1, double d2) { return a(d0, d1, d2, 0); } public final PathEntity a(double d0, double d1, double d2, int i) { // Paper - OBFHELPER
|
|
@@ -153,6 +196,17 @@ public abstract class NavigationAbstract {
|
|
return pathentity;
|
|
}
|
|
}
|
|
+ // Akarin start - Async pathfinder, copied and edited from above with only pathfinding
|
|
+ protected PathEntity findPathAsync(ChunkCache cache, Set<BlockPosition> set, int j) {
|
|
+ if (this.a.locY() < 0.0D) {
|
|
+ return null;
|
|
+ } else if (!this.a()) {
|
|
+ return null;
|
|
+ } else {
|
|
+ return this.t.a(cache, this.a, set, f, j, this.s);
|
|
+ }
|
|
+ }
|
|
+ // Akarin end
|
|
|
|
public boolean a(double d0, double d1, double d2, double d3) {
|
|
return this.a(this.a(d0, d1, d2, 1), d3);
|
|
@@ -246,6 +300,37 @@ public abstract class NavigationAbstract {
|
|
}
|
|
}
|
|
}
|
|
+ // Akarin start - Async pathfinder, copied from above
|
|
+ public void tickAsync() {
|
|
+ ++this.e;
|
|
+ this.doPathfindAsync();
|
|
+ }
|
|
+
|
|
+ // This was copied from above partly with param
|
|
+ public void doTickAsync(PathEntity pathEntity) {
|
|
+ if (shouldContinuePathfind(pathEntity))
|
|
+ return;
|
|
+
|
|
+ Vec3D vec3d;
|
|
+ if (this.a()) {
|
|
+ this.applyPath(pathEntity);
|
|
+ } else if (pathEntity.f() < pathEntity.e()) {
|
|
+ vec3d = this.b();
|
|
+ Vec3D vec3d1 = pathEntity.a(this.a, pathEntity.f());
|
|
+
|
|
+ if (vec3d.y > vec3d1.y && !this.a.onGround && MathHelper.floor(vec3d.x) == MathHelper.floor(vec3d1.x) && MathHelper.floor(vec3d.z) == MathHelper.floor(vec3d1.z))
|
|
+ pathEntity.c(pathEntity.f() + 1);
|
|
+ }
|
|
+
|
|
+ if (shouldContinuePathfind(pathEntity))
|
|
+ return;
|
|
+
|
|
+ vec3d = pathEntity.a((Entity) this.a);
|
|
+ BlockPosition blockposition = new BlockPosition(vec3d);
|
|
+
|
|
+ this.a.getControllerMove().a(vec3d.x, this.b.getType(blockposition.down()).isAir() ? vec3d.y : PathfinderNormal.a((IBlockAccess) this.b, blockposition), vec3d.z, this.d);
|
|
+ }
|
|
+ // Akarin End - Async pathfinder
|
|
|
|
protected void l() {
|
|
Vec3D vec3d = this.b();
|
|
@@ -259,6 +344,20 @@ public abstract class NavigationAbstract {
|
|
|
|
this.a(vec3d);
|
|
}
|
|
+ // Akarin start - Async pathfinder, copied from above with param
|
|
+ protected void applyPath(PathEntity pathEntity) {
|
|
+ Vec3D vec3d = this.b();
|
|
+
|
|
+ this.l = this.a.getWidth() > 0.75F ? this.a.getWidth() / 2.0F : 0.75F - this.a.getWidth() / 2.0F;
|
|
+ Vec3D vec3d1 = pathEntity.g();
|
|
+
|
|
+ if (Math.abs(this.a.locX() - (vec3d1.x + 0.5D)) < (double) this.l && Math.abs(this.a.locZ() - (vec3d1.z + 0.5D)) < (double) this.l && Math.abs(this.a.locY() - vec3d1.y) < 1.0D) {
|
|
+ pathEntity.c(pathEntity.f() + 1);
|
|
+ }
|
|
+
|
|
+ this.applyPath0(pathEntity, vec3d);
|
|
+ }
|
|
+ // Akarin end
|
|
|
|
protected void a(Vec3D vec3d) {
|
|
if (this.e - this.f > 100) {
|
|
@@ -293,10 +392,50 @@ public abstract class NavigationAbstract {
|
|
}
|
|
|
|
}
|
|
+ // Akarin start - Async pathfinder, copied from above with param
|
|
+ protected void applyPath0(PathEntity pathEntity, Vec3D vec3d) {
|
|
+ if (this.e - this.f > 100) {
|
|
+ if (vec3d.distanceSquared(this.g) < 2.25D) {
|
|
+ this.o();
|
|
+ }
|
|
+
|
|
+ this.f = this.e;
|
|
+ this.g = vec3d;
|
|
+ }
|
|
+
|
|
+ if (!pathEntity.b()) {
|
|
+ Vec3D vec3d1 = pathEntity.g();
|
|
+
|
|
+ if (vec3d1.equals(this.h)) {
|
|
+ this.i += SystemUtils.getMonotonicMillis() - this.j;
|
|
+ } else {
|
|
+ this.h = vec3d1;
|
|
+ double d0 = vec3d.f(this.h);
|
|
+
|
|
+ this.k = this.a.dt() > 0.0F ? d0 / (double) this.a.dt() * 1000.0D : 0.0D;
|
|
+ }
|
|
+
|
|
+ if (this.k > 0.0D && (double) this.i > this.k * 3.0D) {
|
|
+ this.h = Vec3D.a;
|
|
+ this.i = 0L;
|
|
+ this.k = 0.0D;
|
|
+ this.o();
|
|
+ }
|
|
+
|
|
+ this.j = SystemUtils.getMonotonicMillis();
|
|
+ }
|
|
+
|
|
+ }
|
|
+ // Akarin end
|
|
|
|
public boolean m() {
|
|
return this.c == null || this.c.b();
|
|
}
|
|
+ // Akarin start - Async pathfinder, copied from above with param
|
|
+ public static boolean shouldContinuePathfind(PathEntity pathEntity) {
|
|
+ return pathEntity == null || pathEntity.b();
|
|
+ }
|
|
+ // Akarin end
|
|
|
|
public boolean n() {
|
|
return !this.m();
|
|
diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
index 67c63cfe333e328cbd00ada970bd81efebfe30b6..848e2fe8b84bfec5be332fd051512eda3838c108 100644
|
|
--- a/src/main/java/net/minecraft/server/Pathfinder.java
|
|
+++ b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
@@ -27,7 +27,7 @@ public class Pathfinder {
|
|
}
|
|
|
|
@Nullable
|
|
- public PathEntity a(ChunkCache chunkcache, EntityInsentient entityinsentient, Set<BlockPosition> set, float f, int i, float f1) {
|
|
+ public synchronized PathEntity a(ChunkCache chunkcache, EntityInsentient entityinsentient, Set<BlockPosition> set, float f, int i, float f1) { // Akarin - synchronized
|
|
this.a.a();
|
|
this.e.a(chunkcache, entityinsentient);
|
|
PathPoint pathpoint = this.e.b();
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderTurtle.java b/src/main/java/net/minecraft/server/PathfinderTurtle.java
|
|
index 59b1fe289c57b9e9f21b74c26cc1836255dad78b..1790878ae9ac33be86bed0b962b8171bf666d119 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderTurtle.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderTurtle.java
|
|
@@ -148,7 +148,7 @@ public class PathfinderTurtle extends PathfinderNormal {
|
|
if (pathtype == PathType.OPEN) {
|
|
AxisAlignedBB axisalignedbb = new AxisAlignedBB((double) i - d2 + 0.5D, (double) j + 0.001D, (double) k - d2 + 0.5D, (double) i + d2 + 0.5D, (double) ((float) j + this.b.getHeight()), (double) k + d2 + 0.5D);
|
|
|
|
- if (!this.b.world.getCubes(this.b, axisalignedbb)) {
|
|
+ if (!this.a.getCubes(this.b, axisalignedbb)) { // Akarin - use chunk cache
|
|
return null;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderWater.java b/src/main/java/net/minecraft/server/PathfinderWater.java
|
|
index 075b63ef57a1528118f03a00c7156b3cb7744969..a3473ddcfe15d329eba78bbd60c00541cb1b88bb 100644
|
|
--- a/src/main/java/net/minecraft/server/PathfinderWater.java
|
|
+++ b/src/main/java/net/minecraft/server/PathfinderWater.java
|
|
@@ -63,7 +63,7 @@ public class PathfinderWater extends PathfinderAbstract {
|
|
@Override
|
|
protected PathPoint a(int i, int j, int k) {
|
|
PathPoint pathpoint = null;
|
|
- PathType pathtype = this.a(this.b.world, i, j, k);
|
|
+ PathType pathtype = this.a(this.a, i, j, k); // Akarin - use chunk cache
|
|
float f = this.b.a(pathtype);
|
|
|
|
if (f >= 0.0F) {
|