mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 23:10:16 +01:00
Fix off by one error for scheduling block ticks (#4014)
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com> Fixes #4015
This commit is contained in:
parent
5791e512b7
commit
dafc7b8f8d
5 changed files with 54 additions and 34 deletions
|
@ -42,7 +42,7 @@ sets the excessive tick delay to the specified ticks (defaults to
|
|||
60 * 20 ticks, aka 60 seconds)
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index bf86444c479f346e7d56f10a7c0ebefd62f08f59..8508b3e10e60a4ce36d471b1d3f7ffc836a6ddf7 100644
|
||||
index f4a56028c21427d1164c5777285114a284b5643c..ee1a690c1b12f28a5282a61917d28deb3ca08f61 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -349,6 +349,13 @@ public class PaperConfig {
|
||||
|
@ -61,10 +61,10 @@ index bf86444c479f346e7d56f10a7c0ebefd62f08f59..8508b3e10e60a4ce36d471b1d3f7ffc8
|
|||
ConfigurationSection section;
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77c5134a7f
|
||||
index 0000000000000000000000000000000000000000..e7624948ea4aa1a07d84ed3d295cfe2dd354fd14
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
|
||||
@@ -0,0 +1,624 @@
|
||||
@@ -0,0 +1,628 @@
|
||||
+package com.destroystokyo.paper.server.ticklist;
|
||||
+
|
||||
+import net.minecraft.server.MCUtil;
|
||||
|
@ -137,7 +137,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ }
|
||||
+ private int shortScheduledIndex;
|
||||
+
|
||||
+ private long nextTick;
|
||||
+ private long currentTick;
|
||||
+
|
||||
+ private static final boolean WARN_ON_EXCESSIVE_DELAY = Boolean.getBoolean("paper.ticklist-warn-on-excessive-delay");
|
||||
+ private static final long EXCESSIVE_DELAY_THRESHOLD = Long.getLong("paper.ticklist-excessive-delay-threshold", 60 * 20).longValue(); // 1 min dfl
|
||||
|
@ -163,7 +163,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper
|
||||
+ this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper
|
||||
+ this.timingFinished = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Finish");
|
||||
+ this.nextTick = this.world.getTime();
|
||||
+ this.currentTick = this.world.getTime();
|
||||
+ }
|
||||
+
|
||||
+ private void queueEntryForTick(final NextTickListEntry<T> entry, final ChunkProviderServer chunkProvider) {
|
||||
|
@ -185,7 +185,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ }
|
||||
+
|
||||
+ private void addToSchedule(final NextTickListEntry<T> entry) {
|
||||
+ long delay = entry.getTargetTick() - this.nextTick;
|
||||
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
|
||||
+ if (delay < SHORT_SCHEDULE_TICK_THRESHOLD) {
|
||||
+ if (delay < 0) {
|
||||
+ // longScheduled orders by tick time, short scheduled does not
|
||||
|
@ -246,7 +246,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ long delay = entry.getTargetTick() - this.nextTick;
|
||||
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
|
||||
+ if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) {
|
||||
+ this.longScheduled.remove(entry);
|
||||
+ }
|
||||
|
@ -266,7 +266,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ }
|
||||
+
|
||||
+ private void prepare() {
|
||||
+ final long currentTick = this.nextTick;
|
||||
+ final long currentTick = this.currentTick;
|
||||
+
|
||||
+ final ChunkProviderServer chunkProvider = this.world.getChunkProvider();
|
||||
+
|
||||
|
@ -334,15 +334,19 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ private boolean warnedAboutDesync;
|
||||
+
|
||||
+ @Override
|
||||
+ public void tick() {
|
||||
+ ++this.nextTick;
|
||||
+ if (this.nextTick != this.world.getTime()) {
|
||||
+ protected void nextTick() {
|
||||
+ ++this.currentTick;
|
||||
+ if (this.currentTick != this.world.getTime()) {
|
||||
+ if (!this.warnedAboutDesync) {
|
||||
+ this.warnedAboutDesync = true;
|
||||
+ MinecraftServer.LOGGER.error("World tick desync detected! Expected " + this.nextTick + " ticks, but got " + this.world.getTime() + " ticks for world '" + this.world.getWorld().getName() + "'", new Throwable());
|
||||
+ MinecraftServer.LOGGER.error("World tick desync detected! Expected " + this.currentTick + " ticks, but got " + this.world.getTime() + " ticks for world '" + this.world.getWorld().getName() + "'", new Throwable());
|
||||
+ MinecraftServer.LOGGER.error("Preventing redstone from breaking by refusing to accept new tick time");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void tick() {
|
||||
+ final ChunkProviderServer chunkProvider = this.world.getChunkProvider();
|
||||
+
|
||||
+ this.world.getMethodProfiler().enter("cleaning");
|
||||
|
@ -479,7 +483,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+
|
||||
+ @Override
|
||||
+ public void schedule(BlockPosition blockPosition, T t, int i, TickListPriority tickListPriority) {
|
||||
+ this.schedule(blockPosition, t, i + this.nextTick, tickListPriority);
|
||||
+ this.schedule(blockPosition, t, i + this.currentTick, tickListPriority);
|
||||
+ }
|
||||
+
|
||||
+ public void schedule(final NextTickListEntry<T> entry) {
|
||||
|
@ -493,7 +497,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ }
|
||||
+
|
||||
+ if (WARN_ON_EXCESSIVE_DELAY) {
|
||||
+ final long delay = entry.getTargetTick() - this.nextTick;
|
||||
+ final long delay = entry.getTargetTick() - this.currentTick;
|
||||
+ if (delay >= EXCESSIVE_DELAY_THRESHOLD) {
|
||||
+ MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable());
|
||||
+ }
|
||||
|
@ -651,7 +655,7 @@ index 0000000000000000000000000000000000000000..bbb042fec32ce5a4aecf1934ab6bed77
|
|||
+ // start copy from TickListServer // TODO check on update
|
||||
+ List<NextTickListEntry<T>> list = this.getEntriesInChunk(chunkcoordintpair, false, true);
|
||||
+
|
||||
+ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.nextTick);
|
||||
+ return TickListServer.serialize(this.getMinecraftKeyFrom, list, this.currentTick);
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
+
|
||||
|
@ -1069,12 +1073,17 @@ index f94234b0a247e378ff9056d6c418464d619a356b..8af1229c3da63a838b0bec1cafde1e41
|
|||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/TickListServer.java b/src/main/java/net/minecraft/server/TickListServer.java
|
||||
index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff8220a95e86 100644
|
||||
index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..3e148b7e99554a1abe257dd3c9acafb914e1ebc8 100644
|
||||
--- a/src/main/java/net/minecraft/server/TickListServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/TickListServer.java
|
||||
@@ -39,6 +39,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -38,7 +38,16 @@ public class TickListServer<T> implements TickList<T> {
|
||||
private final co.aikar.timings.Timing timingTicking; // Paper
|
||||
// Paper end
|
||||
|
||||
+ // Paper start
|
||||
+ protected void nextTick() {}
|
||||
+ // Paper end
|
||||
+
|
||||
public void b() {
|
||||
+ // Paper start - allow overriding
|
||||
+ this.tick();
|
||||
|
@ -1084,7 +1093,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
int i = this.nextTickList.size();
|
||||
|
||||
if (false) { // CraftBukkit
|
||||
@@ -106,10 +111,20 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -106,10 +115,20 @@ public class TickListServer<T> implements TickList<T> {
|
||||
|
||||
@Override
|
||||
public boolean b(BlockPosition blockposition, T t0) {
|
||||
|
@ -1105,7 +1114,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
int i = (chunkcoordintpair.x << 4) - 2;
|
||||
int j = i + 16 + 2;
|
||||
int k = (chunkcoordintpair.z << 4) - 2;
|
||||
@@ -119,6 +134,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -119,6 +138,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public List<NextTickListEntry<T>> a(StructureBoundingBox structureboundingbox, boolean flag, boolean flag1) {
|
||||
|
@ -1117,7 +1126,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
List<NextTickListEntry<T>> list = this.a((List) null, this.nextTickList, structureboundingbox, flag);
|
||||
|
||||
if (flag && list != null) {
|
||||
@@ -158,6 +178,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -158,6 +182,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public void a(StructureBoundingBox structureboundingbox, BlockPosition blockposition) {
|
||||
|
@ -1129,7 +1138,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
List<NextTickListEntry<T>> list = this.a(structureboundingbox, false, false);
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
@@ -175,11 +200,17 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -175,11 +204,17 @@ public class TickListServer<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public NBTTagList a(ChunkCoordIntPair chunkcoordintpair) {
|
||||
|
@ -1147,7 +1156,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
private static <T> NBTTagList a(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) {
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
Iterator iterator = iterable.iterator();
|
||||
@@ -202,11 +233,21 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -202,11 +237,21 @@ public class TickListServer<T> implements TickList<T> {
|
||||
|
||||
@Override
|
||||
public boolean a(BlockPosition blockposition, T t0) {
|
||||
|
@ -1169,7 +1178,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
if (!this.a.test(t0)) {
|
||||
this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.e.getTime(), ticklistpriority));
|
||||
}
|
||||
@@ -222,6 +263,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
@@ -222,6 +267,11 @@ public class TickListServer<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public int a() {
|
||||
|
@ -1182,7 +1191,7 @@ index 3b8f56c0f0507ebdd9ac20be70688b4c0cfe4cf8..149d2b4f929c11b8baf17163bbd6ff82
|
|||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index d41981a5dc4beb9d63f52abea5653067144be932..a8a843f76e4161bb1afb7b44a6cce933a8104001 100644
|
||||
index d41981a5dc4beb9d63f52abea5653067144be932..eebd453bfaeb99b8fdf0d11ee8888f27ad2afff2 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -181,6 +181,15 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
@ -1229,3 +1238,14 @@ index d41981a5dc4beb9d63f52abea5653067144be932..a8a843f76e4161bb1afb7b44a6cce933
|
|||
this.navigators = Sets.newHashSet();
|
||||
this.L = new ObjectLinkedOpenHashSet();
|
||||
this.Q = flag1;
|
||||
@@ -526,7 +544,9 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
if (this.Q) {
|
||||
long i = this.worldData.getTime() + 1L;
|
||||
|
||||
- this.worldDataServer.setTime(i);
|
||||
+ this.worldDataServer.setTime(i); // Paper - diff on change, we want the below to be ran right after this
|
||||
+ this.nextTickListBlock.nextTick(); // Paper
|
||||
+ this.nextTickListFluid.nextTick(); // Paper
|
||||
this.worldDataServer.t().a(this.server, i);
|
||||
if (this.worldData.p().getBoolean(GameRules.DO_DAYLIGHT_CYCLE)) {
|
||||
this.setDayTime(this.worldData.getDayTime() + 1L);
|
||||
|
|
|
@ -23,7 +23,7 @@ index c49d157b8ca25f9811bf64396c207b1c1d6e085d..e895bf811ce5d441541725ade48e3f07
|
|||
private boolean locked = false;
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index a8a843f76e4161bb1afb7b44a6cce933a8104001..815a668c60e6302940545259cce60e2dbe608464 100644
|
||||
index eebd453bfaeb99b8fdf0d11ee8888f27ad2afff2..0e28e829474bea693550b3b2f0e72f97ff9bb10e 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -530,6 +530,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
@ -34,7 +34,7 @@ index a8a843f76e4161bb1afb7b44a6cce933a8104001..815a668c60e6302940545259cce60e2d
|
|||
this.registerEntity(entity2);
|
||||
}
|
||||
|
||||
@@ -1226,6 +1227,19 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
@@ -1228,6 +1229,19 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
||||
public void unregisterEntity(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
|
||||
|
@ -54,7 +54,7 @@ index a8a843f76e4161bb1afb7b44a6cce933a8104001..815a668c60e6302940545259cce60e2d
|
|||
// Spigot start
|
||||
if ( entity instanceof EntityHuman )
|
||||
{
|
||||
@@ -1292,9 +1306,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
@@ -1294,9 +1308,21 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
||||
private void registerEntity(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
|
||||
|
|
|
@ -15,10 +15,10 @@ Combine that with a buggy detail of the previous implementation of
|
|||
the Dupe UUID patch, then this was the likely source of the "Ghost entities"
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 815a668c60e6302940545259cce60e2dbe608464..26f82291ded548f7d623668d95d74833d5211709 100644
|
||||
index 0e28e829474bea693550b3b2f0e72f97ff9bb10e..0038ba4153ce3bb894968ce848f844800361c44a 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -1385,9 +1385,9 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
@@ -1387,9 +1387,9 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
|
||||
private void removeEntityFromChunk(Entity entity) {
|
||||
|
|
|
@ -26,10 +26,10 @@ index 2542b24b0e1919fdc28417df718acd766deefd03..d4207cb622bf17314f77831c604c8ba9
|
|||
EntityTypes<?> entitytypes = entity.getEntityType();
|
||||
int i = entitytypes.getChunkRange() * 16;
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 26f82291ded548f7d623668d95d74833d5211709..3ebb6140b248925c53bc8912d4eeaced00d30fe2 100644
|
||||
index 0038ba4153ce3bb894968ce848f844800361c44a..1fabe0a99e796f423adf4a6c51811b462745c537 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -1351,7 +1351,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
@@ -1353,7 +1353,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ index 26f82291ded548f7d623668d95d74833d5211709..3ebb6140b248925c53bc8912d4eeaced
|
|||
// CraftBukkit start - SPIGOT-5278
|
||||
if (entity instanceof EntityDrowned) {
|
||||
this.navigators.add(((EntityDrowned) entity).navigationWater);
|
||||
@@ -1362,6 +1362,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
@@ -1364,6 +1364,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
this.navigators.add(((EntityInsentient) entity).getNavigation());
|
||||
}
|
||||
entity.valid = true; // CraftBukkit
|
||||
|
|
|
@ -1340,10 +1340,10 @@ index 35f4d2d9591e625ab0bbeab7b606761e74965eec..698d82dd736529a8cbfad5c6bed70ab9
|
|||
this.a.a(t0);
|
||||
this.f();
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 2b04577c153fc4563e59b67afee12411a5de5314..d048ee2313142ba4b0fae7ef2badb9f80614bb62 100644
|
||||
index a54e3ed06a7a1757d3c4ce96b21bed0177e1fa86..63c119072968586fab05ce3990f7c83373736f33 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -707,6 +707,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
@@ -709,6 +709,7 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
gameprofilerfiller.exit();
|
||||
timings.chunkTicksBlocks.stopTiming(); // Paper
|
||||
|
|
Loading…
Reference in a new issue