|
|
|
|
@@ -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);
|
|
|
|
|
|