Upstream has released updates that appears to apply and compile correctly Paper Changes: 81706e626 Make the shutdown thread try to shutdown on main 891824509 Prevent opening inventories when frozen e6d395cc8 Port 04-Util.patch from Tuinity (#3136) 59453f667 Fix incorrectly loading chunks on a cancelled interact event bdcc31caa Let invalid positioned entities clean up previous chunk by the chunkCheck
346 lines
15 KiB
Diff
346 lines
15 KiB
Diff
From 47d8fb20fa43185af04fbe39fd4e250cf275b8a5 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] Async pathfinder
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
|
|
index e9f00a1e1..72fa93d75 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(); // Akarin - remove caller
|
|
//this.world.getMethodProfiler().enter("navigation"); // Akarin - remove caller
|
|
- this.navigation.c();
|
|
+ this.navigation.tickAsync(); // Akarin - Async pathfinder
|
|
//this.world.getMethodProfiler().exit(); // Akarin - remove caller
|
|
//this.world.getMethodProfiler().enter("mob tick"); // Akarin - remove caller
|
|
this.mobTick();
|
|
diff --git a/src/main/java/net/minecraft/server/Navigation.java b/src/main/java/net/minecraft/server/Navigation.java
|
|
index abf450917..4f7f40d5e 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 b763d7f37..e1f3baa7b 100644
|
|
--- a/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
+++ b/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
@@ -22,13 +22,15 @@ public abstract class NavigationAbstract {
|
|
protected long j;
|
|
protected double k;
|
|
protected float l;
|
|
- protected boolean m;
|
|
+ protected boolean m; public boolean needPathfind() { return m; } // Akarin - OBFHELPER
|
|
protected long n;
|
|
protected PathfinderAbstract o;
|
|
- private BlockPosition q;
|
|
+ private BlockPosition q; public BlockPosition origin() { return q; } // Akarin - OBFHELPER
|
|
private int r;
|
|
private float s;
|
|
private final Pathfinder t; public Pathfinder getPathfinder() { return this.t; } // Paper - OBFHELPER
|
|
+ private long lastPathfindAsync; // Akarin - Async pathfinder
|
|
+ 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 - Async pathfinder
|
|
|
|
public NavigationAbstract(EntityInsentient entityinsentient, World world) {
|
|
this.g = Vec3D.a;
|
|
@@ -65,7 +67,7 @@ public abstract class NavigationAbstract {
|
|
return this.m;
|
|
}
|
|
|
|
- public void j() {
|
|
+ public void doPathfind() { j(); } public void j() { // Akarin - OBFHELPER
|
|
if (this.b.getTime() - this.n > 20L) {
|
|
if (this.q != null) {
|
|
this.c = null;
|
|
@@ -78,6 +80,37 @@ public abstract class NavigationAbstract {
|
|
}
|
|
|
|
}
|
|
+ // Akarin Start - Async pathfinder
|
|
+ public void doPathfindAsync() {
|
|
+ if (this.b.getTime() - this.lastPathfindAsync > 20L) {
|
|
+ if (this.q != null) {
|
|
+ this.lastPathfindAsync = this.b.getTime();
|
|
+
|
|
+ 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));
|
|
+
|
|
+ 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 {
|
|
+ doTickAsync(this.c);
|
|
+ }
|
|
+ }
|
|
+ // Akarin End - Async pathfinder
|
|
|
|
@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
|
|
@@ -106,7 +139,7 @@ public abstract class NavigationAbstract {
|
|
|
|
@Nullable
|
|
// Paper start - Add target
|
|
- protected PathEntity a(Set<BlockPosition> set, int i, boolean flag, int j) {
|
|
+ protected PathEntity findPath(Set<BlockPosition> set, int i, boolean flag, int j) { return a(set, 1, flag, j); } protected PathEntity a(Set<BlockPosition> set, int i, boolean flag, int j) { // Akarin - OBFHELPER
|
|
return this.a(set, null, i, flag, j);
|
|
}
|
|
@Nullable protected PathEntity a(Set<BlockPosition> set, Entity target, int i, boolean flag, int j) {
|
|
@@ -153,6 +186,17 @@ public abstract class NavigationAbstract {
|
|
return pathentity;
|
|
}
|
|
}
|
|
+ // Akarin Start - Async pathfinder
|
|
+ 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 - Async pathfinder
|
|
|
|
public boolean a(double d0, double d1, double d2, double d3) {
|
|
return this.a(this.a(d0, d1, d2, 1), d3);
|
|
@@ -217,7 +261,7 @@ public abstract class NavigationAbstract {
|
|
return this.c;
|
|
}
|
|
|
|
- public void c() {
|
|
+ public void doTick() { c(); } public void c() { // Akarin - OBFHELPER
|
|
++this.e;
|
|
if (this.m) {
|
|
this.j();
|
|
@@ -246,6 +290,84 @@ public abstract class NavigationAbstract {
|
|
}
|
|
}
|
|
}
|
|
+ // Akarin Start - Async pathfinder
|
|
+ public void tickAsync() {
|
|
+ ++this.e;
|
|
+ this.doPathfindAsync();
|
|
+ }
|
|
+
|
|
+ public void doTickAsync(PathEntity pathEntity) {
|
|
+ if (shouldContinuePathfind(pathEntity)) return;
|
|
+
|
|
+ Vec3D vec3d;
|
|
+
|
|
+ if (this.a()) {
|
|
+ applyUnitAsync(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);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // PacketDebug.a(this.b, this.a, pathEntity, this.l);
|
|
+ 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);
|
|
+ }
|
|
+
|
|
+ protected void applyUnitAsync(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.setUnitAsync(pathEntity, vec3d);
|
|
+ }
|
|
+
|
|
+ protected void setUnitAsync(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 - Async pathfinder
|
|
|
|
protected void l() {
|
|
Vec3D vec3d = this.b();
|
|
@@ -294,9 +416,14 @@ public abstract class NavigationAbstract {
|
|
|
|
}
|
|
|
|
- public boolean m() {
|
|
+ public boolean shouldContinuePathfind() { return m(); } public boolean m() { // Akarin - OBFHELPER
|
|
return this.c == null || this.c.b();
|
|
}
|
|
+ // Akarin Start - Async pathfinder
|
|
+ public boolean shouldContinuePathfind(PathEntity pathEntity) {
|
|
+ return pathEntity == null || pathEntity.b();
|
|
+ }
|
|
+ // Akarin End - Async pathfinder
|
|
|
|
public boolean n() {
|
|
return !this.m();
|
|
@@ -307,9 +434,9 @@ public abstract class NavigationAbstract {
|
|
this.c = null;
|
|
}
|
|
|
|
- protected abstract Vec3D b();
|
|
+ protected Vec3D getEntityPathfindUnit() { return b(); } protected abstract Vec3D b(); // Akarin - OBFHELPER
|
|
|
|
- protected abstract boolean a();
|
|
+ protected boolean canPathfind() { return a(); } protected abstract boolean a(); // Akarin - OBFHELPER
|
|
|
|
protected boolean p() {
|
|
return this.a.az() || this.a.aH();
|
|
diff --git a/src/main/java/net/minecraft/server/PathEntity.java b/src/main/java/net/minecraft/server/PathEntity.java
|
|
index dcb4e2508..265b6df4f 100644
|
|
--- a/src/main/java/net/minecraft/server/PathEntity.java
|
|
+++ b/src/main/java/net/minecraft/server/PathEntity.java
|
|
@@ -110,7 +110,7 @@ public class PathEntity {
|
|
return "Path(length=" + this.a.size() + ")";
|
|
}
|
|
|
|
- public BlockPosition k() {
|
|
+ public BlockPosition origin() { return k(); } public BlockPosition k() { // Akarin - OBFHELPER
|
|
return this.f;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Pathfinder.java b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
index 67c63cfe3..00bd2327f 100644
|
|
--- a/src/main/java/net/minecraft/server/Pathfinder.java
|
|
+++ b/src/main/java/net/minecraft/server/Pathfinder.java
|
|
@@ -15,9 +15,9 @@ import javax.annotation.Nullable;
|
|
|
|
public class Pathfinder {
|
|
|
|
- private final Path a = new Path();
|
|
- private final Set<PathPoint> b = Sets.newHashSet();
|
|
- private final PathPoint[] c = new PathPoint[32];
|
|
+ private final Path a = new Path(); private Path nodePath() { return this.a; } // Akarin - OBFHELPER
|
|
+ private final Set<PathPoint> b = Sets.newHashSet(); private Set<PathPoint> nodesSet() { return this.b; } // Akarin - OBFHELPER
|
|
+ private final PathPoint[] c = new PathPoint[32]; private PathPoint[] pathNodes() { return this.c; } // Akarin - OBFHELPER
|
|
private final int d;
|
|
private final PathfinderAbstract e; public PathfinderAbstract getPathfinder() { return this.e; } // Paper - OBFHELPER
|
|
|
|
@@ -26,8 +26,9 @@ public class Pathfinder {
|
|
this.d = i;
|
|
}
|
|
|
|
+ public PathEntity findPaths(ChunkCache chunkcache, EntityInsentient entityinsentient, Set<BlockPosition> set, float f, int i, float f1) { return a(chunkcache, entityinsentient, set, f, i, f1); } // Akarin - OBFHELPER
|
|
@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) {
|
|
this.a.a();
|
|
this.e.a(chunkcache, entityinsentient);
|
|
PathPoint pathpoint = this.e.b();
|
|
@@ -40,6 +41,7 @@ public class Pathfinder {
|
|
return pathentity;
|
|
}
|
|
|
|
+ private PathEntity findPaths0(PathPoint pathpoint, Map<PathDestination, BlockPosition> map, float f, int i, float f1) { return a(pathpoint, map, f, i, f1); } // Akarin - OBFHELPER
|
|
@Nullable
|
|
private PathEntity a(PathPoint pathpoint, Map<PathDestination, BlockPosition> map, float f, int i, float f1) {
|
|
Set<PathDestination> set = map.keySet();
|
|
@@ -117,6 +119,7 @@ public class Pathfinder {
|
|
}
|
|
}
|
|
|
|
+ private float getNearestDistance(PathPoint pathpoint, Set<PathDestination> set) { return a(pathpoint, set); } // Akarin - OBFHELPER
|
|
private float a(PathPoint pathpoint, Set<PathDestination> set) {
|
|
float f = Float.MAX_VALUE;
|
|
|
|
@@ -132,6 +135,7 @@ public class Pathfinder {
|
|
return f;
|
|
}
|
|
|
|
+ private PathEntity gatherAssociatedNodes(PathPoint pathpoint, BlockPosition blockposition, boolean flag) { return a(pathpoint, blockposition, flag); } // Akarin - OBFHELPER
|
|
private PathEntity a(PathPoint pathpoint, BlockPosition blockposition, boolean flag) {
|
|
List<PathPoint> list = Lists.newArrayList();
|
|
PathPoint pathpoint1 = pathpoint;
|
|
diff --git a/src/main/java/net/minecraft/server/PathfinderTurtle.java b/src/main/java/net/minecraft/server/PathfinderTurtle.java
|
|
index 59b1fe289..1790878ae 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 075b63ef5..a3473ddcf 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) {
|
|
--
|
|
2.20.1
|
|
|