Improve Chunk Prioritization and Internal Scheduler

In previous MC versions, we had a rather simple internal scheduler
for delayed tasks that would just keep pushing task back until desired
tick was reached.

The method it called to schedule the task changed behavior in 1.14, and now
this scheduler is not working nowhere near what it was supposed to be doing.

This was causing long delayed task to eat up CPU (In Oversleep for example)

Rewrite this to just use the CraftScheduler for scheduling delayed tasks.

Once this was fixed, it became quite clear the code that delayed ticket
additions for chunks based on distance was clearly not right, as it was
tested on the previous broken logic.

So the ticket delay process has been vastly revamped to be even smarter.
Chunks behind the player can load slower than the chunks in front of the player.
We also can delay ticket adding until one of its neighbors has loaded, as
this lets us get a smoother spiral out for the chunks (minus frustum intent).

Additionally on frustum previous commit inadvertently broke frustum trying to
fix an issue when the real fix lied elsewhere, so restore chunk priority so
it works again.
This commit is contained in:
Aikar 2020-06-09 03:17:25 -04:00
parent 24a2e80431
commit b2d81e21c5
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE
19 changed files with 417 additions and 162 deletions

View file

@ -3317,10 +3317,10 @@ index 75308712d0642d5ab168de653023349df8aee5ed..aa7501d366b15e7f7f64b7d98a1dccff
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaa6e33b0e5df2549e4f989501bacfd1ab4ad063
index 0000000000000000000000000000000000000000..16302c4ac6d3e40318a762cea0afcf3f94715216
--- /dev/null
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -0,0 +1,532 @@
@@ -0,0 +1,514 @@
+package net.minecraft.server;
+
+import com.destroystokyo.paper.block.TargetBlockInfo;
@ -3568,30 +3568,12 @@ index 0000000000000000000000000000000000000000..aaa6e33b0e5df2549e4f989501bacfd1
+ return MinecraftServer.getServer().isMainThread();
+ }
+
+ private static class DelayedRunnable implements Runnable {
+
+ private final int ticks;
+ private final Runnable run;
+
+ private DelayedRunnable(int ticks, Runnable run) {
+ this.ticks = ticks;
+ this.run = run;
+ }
+
+ @Override
+ public void run() {
+ if (ticks <= 0) {
+ run.run();
+ } else {
+ scheduleTask(ticks-1, run);
+ }
+ }
+ public static org.bukkit.scheduler.BukkitTask scheduleTask(int ticks, Runnable runnable) {
+ return scheduleTask(ticks, runnable, null);
+ }
+
+ public static void scheduleTask(int ticks, Runnable runnable) {
+ // We use post to main instead of process queue as we don't want to process these mid tick if
+ // Someone uses processQueueWhileWaiting
+ MinecraftServer.getServer().scheduleOnMain(new DelayedRunnable(ticks, runnable));
+ public static org.bukkit.scheduler.BukkitTask scheduleTask(int ticks, Runnable runnable, String taskName) {
+ return MinecraftServer.getServer().server.getScheduler().scheduleInternalTask(runnable, ticks, taskName);
+ }
+
+ public static void processQueue() {
@ -4495,6 +4477,194 @@ index e181df6f4d08b88835db7342f97e0b848bcf01ef..4a9132c7016b076ab35b5d66ce81bbd2
/**
* Mirror
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 9ad17c560c8d99a396543ab9f97c34de648f6544..533c0bc55fc7ac4cc1f493f898a85a6617371031 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -43,6 +43,7 @@ import org.bukkit.scheduler.BukkitWorker;
*/
public class CraftScheduler implements BukkitScheduler {
+ static Plugin MINECRAFT = new MinecraftInternalPlugin();
/**
* Counter for IDs. Order doesn't matter, only uniqueness.
*/
@@ -177,6 +178,11 @@ public class CraftScheduler implements BukkitScheduler {
runTaskTimer(plugin, (Object) task, delay, period);
}
+ public BukkitTask scheduleInternalTask(Runnable run, int delay, String taskName) {
+ final CraftTask task = new CraftTask(run, nextId(), taskName);
+ return handle(task, delay);
+ }
+
public BukkitTask runTaskTimer(Plugin plugin, Object runnable, long delay, long period) {
validate(plugin, runnable);
if (delay < 0L) {
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 3f55381c152b9841b524f623c9b32360e97cb8ed..d85e21b75054067b926ecfee89d62c6dd0744189 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -39,6 +39,21 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
CraftTask(final Object task) {
this(null, task, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
}
+ // Paper start
+ public String taskName = null;
+ boolean internal = false;
+ CraftTask(final Object task, int id, String taskName) {
+ this.rTask = (Runnable) task;
+ this.cTask = null;
+ this.plugin = CraftScheduler.MINECRAFT;
+ this.taskName = taskName;
+ this.internal = true;
+ this.id = id;
+ this.period = CraftTask.NO_REPEATING;
+ this.taskName = taskName;
+ this.timings = null; // Will be changed in later patch
+ }
+ // Paper end
CraftTask(final Plugin plugin, final Object task, final int id, final long period) {
this.plugin = plugin;
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java b/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java
new file mode 100644
index 0000000000000000000000000000000000000000..49dc0c441b9dd7e7745cf15ced67f383ebee1f99
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/MinecraftInternalPlugin.java
@@ -0,0 +1,132 @@
+package org.bukkit.craftbukkit.scheduler;
+
+
+import org.bukkit.Server;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.generator.ChunkGenerator;
+import org.bukkit.plugin.PluginBase;
+import org.bukkit.plugin.PluginDescriptionFile;
+import org.bukkit.plugin.PluginLoader;
+import org.bukkit.plugin.PluginLogger;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.List;
+
+public class MinecraftInternalPlugin extends PluginBase {
+ private boolean enabled = true;
+
+ private final String pluginName;
+ private PluginDescriptionFile pdf;
+
+ public MinecraftInternalPlugin() {
+ this.pluginName = "Minecraft";
+ pdf = new PluginDescriptionFile(pluginName, "1.0", "nms");
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ @Override
+ public File getDataFolder() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public PluginDescriptionFile getDescription() {
+ return pdf;
+ }
+
+ @Override
+ public FileConfiguration getConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public InputStream getResource(String filename) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void saveConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void saveDefaultConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void saveResource(String resourcePath, boolean replace) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void reloadConfig() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public PluginLogger getLogger() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public PluginLoader getPluginLoader() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public Server getServer() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void onDisable() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void onLoad() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void onEnable() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public boolean isNaggable() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public void setNaggable(boolean canNag) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ @Override
+ public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java
index d8358a0f031ca6e5d5dc1700172175446f74384e..d0b813008ca21fe6aa9b514ed4325596113fd459 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java

View file

@ -6,10 +6,10 @@ Subject: [PATCH] Timings v2
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
new file mode 100644
index 0000000000000000000000000000000000000000..11c5f8e033689f483a64486d2f8c206ca26ff9da
index 0000000000000000000000000000000000000000..a58ef60d9976b3afc50e94364cf474bd2e5fdfd6
--- /dev/null
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -0,0 +1,145 @@
@@ -0,0 +1,149 @@
+package co.aikar.timings;
+
+import com.google.common.collect.MapMaker;
@ -58,6 +58,10 @@ index 0000000000000000000000000000000000000000..11c5f8e033689f483a64486d2f8c206c
+
+ private MinecraftTimings() {}
+
+ public static Timing getInternalTaskName(String taskName) {
+ return Timings.ofSafe(taskName);
+ }
+
+ /**
+ * Gets a timer associated with a plugins tasks.
+ * @param bukkitTask
@ -2015,7 +2019,7 @@ index db0bd5cc0acb5523815183ba9c4a8b853a9e9d12..48d1397a6846c64dfa372390783ce668
public Player.Spigot spigot()
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696155f7160 100644
index 533c0bc55fc7ac4cc1f493f898a85a6617371031..de332758e03a563a9b72c134332db9e6a1c5ed2b 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -1,5 +1,6 @@
@ -2025,7 +2029,17 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.ArrayList;
import java.util.Comparator;
@@ -254,7 +255,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -179,7 +180,8 @@ public class CraftScheduler implements BukkitScheduler {
}
public BukkitTask scheduleInternalTask(Runnable run, int delay, String taskName) {
- final CraftTask task = new CraftTask(run, nextId(), taskName);
+ final CraftTask task = new CraftTask(run, nextId(), "Internal - " + (taskName != null ? taskName : "Unknown"));
+ task.internal = true;
return handle(task, delay);
}
@@ -260,7 +262,7 @@ public class CraftScheduler implements BukkitScheduler {
}
return false;
}
@ -2034,7 +2048,7 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -289,7 +290,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -295,7 +297,7 @@ public class CraftScheduler implements BukkitScheduler {
}
}
}
@ -2043,7 +2057,7 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
handle(task, 0L);
for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) {
if (taskPending == task) {
@@ -396,9 +397,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -402,9 +404,7 @@ public class CraftScheduler implements BukkitScheduler {
if (task.isSync()) {
currentTask = task;
try {
@ -2053,7 +2067,7 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
} catch (final Throwable throwable) {
task.getOwner().getLogger().log(
Level.WARNING,
@@ -425,8 +424,10 @@ public class CraftScheduler implements BukkitScheduler {
@@ -431,8 +431,10 @@ public class CraftScheduler implements BukkitScheduler {
runners.remove(task.getTaskId());
}
}
@ -2064,7 +2078,7 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
debugHead = debugHead.getNextHead(currentTick);
}
@@ -459,6 +460,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -465,6 +467,7 @@ public class CraftScheduler implements BukkitScheduler {
}
private void parsePending() {
@ -2072,7 +2086,7 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
CraftTask head = this.head;
CraftTask task = head.getNext();
CraftTask lastTask = head;
@@ -477,6 +479,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -483,6 +486,7 @@ public class CraftScheduler implements BukkitScheduler {
task.setNext(null);
}
this.head = lastTask;
@ -2081,7 +2095,7 @@ index 9ad17c560c8d99a396543ab9f97c34de648f6544..db433ed3707a1cb3a6df13b3c3fb5696
private boolean isReady(final int currentTick) {
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 3f55381c152b9841b524f623c9b32360e97cb8ed..0d9a466809be6733fcb7e5421318477da333850f 100644
index d85e21b75054067b926ecfee89d62c6dd0744189..ce495907f13dd10b5daba521101a78d65a2e8836 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -1,9 +1,11 @@
@ -2114,16 +2128,21 @@ index 3f55381c152b9841b524f623c9b32360e97cb8ed..0d9a466809be6733fcb7e5421318477d
CraftTask() {
this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
}
@@ -40,7 +42,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this(null, task, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
@@ -51,11 +53,11 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this.id = id;
this.period = CraftTask.NO_REPEATING;
this.taskName = taskName;
- this.timings = null; // Will be changed in later patch
+ this.timings = MinecraftTimings.getInternalTaskName(taskName);
}
// Paper end
- CraftTask(final Plugin plugin, final Object task, final int id, final long period) {
+ CraftTask(final Plugin plugin, final Object task, final int id, final long period) { // Paper
this.plugin = plugin;
if (task instanceof Runnable) {
this.rTask = (Runnable) task;
@@ -57,7 +59,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@@ -72,7 +74,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
}
this.id = id;
this.period = period;
@ -2132,7 +2151,7 @@ index 3f55381c152b9841b524f623c9b32360e97cb8ed..0d9a466809be6733fcb7e5421318477d
}
@Override
@@ -77,11 +79,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@@ -92,11 +94,13 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@Override
public void run() {
@ -2146,7 +2165,7 @@ index 3f55381c152b9841b524f623c9b32360e97cb8ed..0d9a466809be6733fcb7e5421318477d
}
long getPeriod() {
@@ -108,7 +112,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@@ -123,7 +127,7 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
this.next = next;
}
@ -2155,7 +2174,7 @@ index 3f55381c152b9841b524f623c9b32360e97cb8ed..0d9a466809be6733fcb7e5421318477d
return (rTask != null) ? rTask.getClass() : ((cTask != null) ? cTask.getClass() : null);
}
@@ -132,9 +136,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
@@ -147,9 +151,4 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot
return true;
}

View file

@ -5,7 +5,7 @@ Subject: [PATCH] Optimize TileEntity Ticking
diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java
index 35f4dc75fbc7cccc80453f279a08b286ab32a25a..c4766f729fed7c9da9e456cae044400e2d08400c 100644
index 35f4dc75fbc7cccc80453f279a08b286ab32a25a..eb2b6ff8fd86233c434882c69a8890adc9861d4b 100644
--- a/src/main/java/net/minecraft/server/TileEntityChest.java
+++ b/src/main/java/net/minecraft/server/TileEntityChest.java
@@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.entity.CraftHumanEntity;
@ -61,7 +61,7 @@ index 35f4dc75fbc7cccc80453f279a08b286ab32a25a..c4766f729fed7c9da9e456cae044400e
+ */
+ MCUtil.scheduleTask(10, () -> {
+ this.a(SoundEffects.BLOCK_CHEST_CLOSE);
+ });
+ }, "Chest Sounds");
+ //} // Paper end
if (this.a < 0.0F) {
@ -91,7 +91,7 @@ index 35f4dc75fbc7cccc80453f279a08b286ab32a25a..c4766f729fed7c9da9e456cae044400e
int newPower = Math.max(0, Math.min(15, this.viewingCount));
diff --git a/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
index 68737be5e67b52cb1f9f526b58b589ecba14dd6b..17c39edca08e6db5da5f0de5d70cb2c64e8cd7df 100644
index 68737be5e67b52cb1f9f526b58b589ecba14dd6b..ea2d5cdd38b305563e9f979887eb455095928ec9 100644
--- a/src/main/java/net/minecraft/server/TileEntityEnderChest.java
+++ b/src/main/java/net/minecraft/server/TileEntityEnderChest.java
@@ -1,6 +1,6 @@
@ -163,7 +163,7 @@ index 68737be5e67b52cb1f9f526b58b589ecba14dd6b..17c39edca08e6db5da5f0de5d70cb2c6
+ MCUtil.scheduleTask(10, () -> {
this.world.playSound((EntityHuman) null, d0, (double) j + 0.5D, d2, SoundEffects.BLOCK_ENDER_CHEST_CLOSE, SoundCategory.BLOCKS, 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F);
- }
+ });
+ }, "Chest Sounds");
if (this.a < 0.0F) {
this.a = 0.0F;

View file

@ -209,7 +209,7 @@ index d5e9bae7097460b44f9061198cf54b421bf2b3cf..1bcf01c09a9ba5168d491797e13eeddc
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index fc9bbc4fdd371931ea31c061b9bef0c4f91853d9..6e7d3573ed6f58a9c5f29c8b1b49746f13e21dc7 100644
index 9a9a7ae659dd1aea5111603852fbda9fad707be2..6e4329d21d7877e46369361e55954f2f9371bd6e 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -2,6 +2,9 @@ package net.minecraft.server;
@ -260,7 +260,7 @@ index 19e68a78310de787bca701bc2597c64e34a77d7c..a2a25cf6a43a1f59a80c997e2980f2bb
} finally {
if (pushbackinputstream != null) {
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index db433ed3707a1cb3a6df13b3c3fb5696155f7160..d05a9ae0fbdc8c9d86109a631d059299e51a2a39 100644
index de332758e03a563a9b72c134332db9e6a1c5ed2b..e68533176a0c07560118531600304fa76a1c3fc6 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -16,6 +16,9 @@ import java.util.concurrent.atomic.AtomicInteger;
@ -273,7 +273,7 @@ index db433ed3707a1cb3a6df13b3c3fb5696155f7160..d05a9ae0fbdc8c9d86109a631d059299
import org.apache.commons.lang.Validate;
import org.bukkit.plugin.IllegalPluginAccessException;
import org.bukkit.plugin.Plugin;
@@ -399,20 +402,26 @@ public class CraftScheduler implements BukkitScheduler {
@@ -406,20 +409,26 @@ public class CraftScheduler implements BukkitScheduler {
try {
task.run();
} catch (final Throwable throwable) {

View file

@ -9,10 +9,10 @@ One report of a suspected memory leak with the system.
This adds additional overhead to asynchronous task dispatching
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index d05a9ae0fbdc8c9d86109a631d059299e51a2a39..8c48130db03e1baffa341222caa6a82b29525671 100644
index e68533176a0c07560118531600304fa76a1c3fc6..ff855035ae55df37d68b284ac18976c46d388af2 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -420,7 +420,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -427,7 +427,7 @@ public class CraftScheduler implements BukkitScheduler {
}
parsePending();
} else {
@ -21,7 +21,7 @@ index d05a9ae0fbdc8c9d86109a631d059299e51a2a39..8c48130db03e1baffa341222caa6a82b
executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
// We don't need to parse pending
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
@@ -437,7 +437,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -444,7 +444,7 @@ public class CraftScheduler implements BukkitScheduler {
pending.addAll(temp);
temp.clear();
MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming();
@ -30,7 +30,7 @@ index d05a9ae0fbdc8c9d86109a631d059299e51a2a39..8c48130db03e1baffa341222caa6a82b
}
private void addTask(final CraftTask task) {
@@ -497,10 +497,15 @@ public class CraftScheduler implements BukkitScheduler {
@@ -504,10 +504,15 @@ public class CraftScheduler implements BukkitScheduler {
@Override
public String toString() {

View file

@ -403,7 +403,7 @@ index 0000000000000000000000000000000000000000..3aceb0ea8a1a3ed94dd8a9e954c52ecd
+ }
+}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index aaa6e33b0e5df2549e4f989501bacfd1ab4ad063..8ebe5a2e2678fccb17aced57f6fd1e52c17935db 100644
index 16302c4ac6d3e40318a762cea0afcf3f94715216..148917547bb7a626d1b2bacce7385607043db7e2 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -1,8 +1,11 @@
@ -418,7 +418,7 @@ index aaa6e33b0e5df2549e4f989501bacfd1ab4ad063..8ebe5a2e2678fccb17aced57f6fd1e52
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftWorld;
@@ -355,6 +358,10 @@ public final class MCUtil {
@@ -337,6 +340,10 @@ public final class MCUtil {
return run.get();
}
@ -430,7 +430,7 @@ index aaa6e33b0e5df2549e4f989501bacfd1ab4ad063..8ebe5a2e2678fccb17aced57f6fd1e52
* Calculates distance between 2 entities
* @param e1
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 87595425a358a13c8f2393619d51a981140556cf..4a513aaea587414cf6abc1c136e52420d59688d8 100644
index ed32242bd169e9f28607942aa31aa48a5799b215..54f80cb8e1b771f2a493543e04f8bc8346a391dc 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1304,7 +1304,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas

View file

@ -159,10 +159,10 @@ index 0000000000000000000000000000000000000000..3c1992e212a6d6f1db4d5b807b38d719
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b469e30ba 100644
index ff855035ae55df37d68b284ac18976c46d388af2..99ea0aabadfac2a68ec67a7d49831025820de2c3 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -62,7 +62,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -63,7 +63,7 @@ public class CraftScheduler implements BukkitScheduler {
/**
* Main thread logic only
*/
@ -171,7 +171,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
new Comparator<CraftTask>() {
@Override
public int compare(final CraftTask o1, final CraftTask o2) {
@@ -79,12 +79,13 @@ public class CraftScheduler implements BukkitScheduler {
@@ -80,12 +80,13 @@ public class CraftScheduler implements BukkitScheduler {
/**
* These are tasks that are currently active. It's provided for 'viewing' the current state.
*/
@ -187,7 +187,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
private final Executor executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %d").build());
private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {
@Override
@@ -93,12 +94,31 @@ public class CraftScheduler implements BukkitScheduler {
@@ -94,12 +95,31 @@ public class CraftScheduler implements BukkitScheduler {
}
};
private CraftAsyncDebugger debugTail = debugHead;
@ -219,7 +219,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
@Override
public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task) {
return this.scheduleSyncDelayedTask(plugin, task, 0L);
@@ -215,7 +235,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -222,7 +242,7 @@ public class CraftScheduler implements BukkitScheduler {
} else if (period < CraftTask.NO_REPEATING) {
period = CraftTask.NO_REPEATING;
}
@ -228,7 +228,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
}
@Override
@@ -231,6 +251,11 @@ public class CraftScheduler implements BukkitScheduler {
@@ -238,6 +258,11 @@ public class CraftScheduler implements BukkitScheduler {
if (taskId <= 0) {
return;
}
@ -240,7 +240,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
CraftTask task = runners.get(taskId);
if (task != null) {
task.cancel0();
@@ -273,6 +298,11 @@ public class CraftScheduler implements BukkitScheduler {
@@ -280,6 +305,11 @@ public class CraftScheduler implements BukkitScheduler {
@Override
public void cancelTasks(final Plugin plugin) {
Validate.notNull(plugin, "Cannot cancel tasks of null plugin");
@ -252,7 +252,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
final CraftTask task = new CraftTask(
new Runnable() {
@Override
@@ -312,6 +342,13 @@ public class CraftScheduler implements BukkitScheduler {
@@ -319,6 +349,13 @@ public class CraftScheduler implements BukkitScheduler {
@Override
public boolean isCurrentlyRunning(final int taskId) {
@ -266,7 +266,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
final CraftTask task = runners.get(taskId);
if (task == null) {
return false;
@@ -330,6 +367,11 @@ public class CraftScheduler implements BukkitScheduler {
@@ -337,6 +374,11 @@ public class CraftScheduler implements BukkitScheduler {
if (taskId <= 0) {
return false;
}
@ -278,7 +278,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
for (CraftTask task = head.getNext(); task != null; task = task.getNext()) {
if (task.getTaskId() == taskId) {
return task.getPeriod() >= CraftTask.NO_REPEATING; // The task will run
@@ -341,6 +383,12 @@ public class CraftScheduler implements BukkitScheduler {
@@ -348,6 +390,12 @@ public class CraftScheduler implements BukkitScheduler {
@Override
public List<BukkitWorker> getActiveWorkers() {
@ -291,7 +291,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
final ArrayList<BukkitWorker> workers = new ArrayList<BukkitWorker>();
for (final CraftTask taskObj : runners.values()) {
// Iterator will be a best-effort (may fail to grab very new values) if called from an async thread
@@ -378,6 +426,11 @@ public class CraftScheduler implements BukkitScheduler {
@@ -385,6 +433,11 @@ public class CraftScheduler implements BukkitScheduler {
pending.add(task);
}
}
@ -303,7 +303,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
return pending;
}
@@ -385,6 +438,11 @@ public class CraftScheduler implements BukkitScheduler {
@@ -392,6 +445,11 @@ public class CraftScheduler implements BukkitScheduler {
* This method is designed to never block or wait for locks; an immediate execution of all current tasks.
*/
public void mainThreadHeartbeat(final int currentTick) {
@ -315,7 +315,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
this.currentTick = currentTick;
final List<CraftTask> temp = this.temp;
parsePending();
@@ -421,7 +479,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -428,7 +486,7 @@ public class CraftScheduler implements BukkitScheduler {
parsePending();
} else {
//debugTail = debugTail.setNext(new CraftAsyncDebugger(currentTick + RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
@ -324,7 +324,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
// We don't need to parse pending
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
}
@@ -440,7 +498,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -447,7 +505,7 @@ public class CraftScheduler implements BukkitScheduler {
//debugHead = debugHead.getNextHead(currentTick); // Paper
}
@ -333,7 +333,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
final AtomicReference<CraftTask> tail = this.tail;
CraftTask tailTask = tail.get();
while (!tail.compareAndSet(tailTask, task)) {
@@ -449,7 +507,13 @@ public class CraftScheduler implements BukkitScheduler {
@@ -456,7 +514,13 @@ public class CraftScheduler implements BukkitScheduler {
tailTask.setNext(task);
}
@ -348,7 +348,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
task.setNextRun(currentTick + delay);
addTask(task);
return task;
@@ -468,8 +532,8 @@ public class CraftScheduler implements BukkitScheduler {
@@ -475,8 +539,8 @@ public class CraftScheduler implements BukkitScheduler {
return ids.incrementAndGet();
}
@ -359,7 +359,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b
CraftTask head = this.head;
CraftTask task = head.getNext();
CraftTask lastTask = head;
@@ -488,7 +552,7 @@ public class CraftScheduler implements BukkitScheduler {
@@ -495,7 +559,7 @@ public class CraftScheduler implements BukkitScheduler {
task.setNext(null);
}
this.head = lastTask;

View file

@ -39,10 +39,10 @@ index 0f74ec89b3e85c918c95f9d8fef6d68403ed1107..4609e402b419ed21e17ad34d02dca55b
this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible"));
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 8ebe5a2e2678fccb17aced57f6fd1e52c17935db..45179aec0d91149ba9cc4d95e65c489ce695053d 100644
index 148917547bb7a626d1b2bacce7385607043db7e2..49178cbcebe7e7af9e9a2485ae11058fd1c6b20f 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -536,4 +536,19 @@ public final class MCUtil {
@@ -518,4 +518,19 @@ public final class MCUtil {
return null;
}
}

View file

@ -198,7 +198,7 @@ index 8c6550433c20c54cbe390219821ce393c5720da8..e6d08756f76360b29b29f18305e5ec84
public final ChunkGenerator<?> chunkGenerator;
private final WorldServer world;
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 45179aec0d91149ba9cc4d95e65c489ce695053d..20f54baacebe98435539d4cbef41f182040db2e9 100644
index 49178cbcebe7e7af9e9a2485ae11058fd1c6b20f..ece411feee81f96ae0462cf7643ec450cafad7a7 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -5,7 +5,13 @@ import com.destroystokyo.paper.profile.CraftPlayerProfile;
@ -227,7 +227,7 @@ index 45179aec0d91149ba9cc4d95e65c489ce695053d..20f54baacebe98435539d4cbef41f182
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
@@ -551,4 +560,170 @@ public final class MCUtil {
@@ -533,4 +542,170 @@ public final class MCUtil {
return null;
}

View file

@ -2935,10 +2935,10 @@ index 2f95174fcc467908808ed3f2dc956bdcafdc3558..134c76065bf382912e6c28d15449db3f
+// Paper end
}
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 20f54baacebe98435539d4cbef41f182040db2e9..9f8c0e10e42d233a8b74ee5a71fb8fb6ea8e7480 100644
index ece411feee81f96ae0462cf7643ec450cafad7a7..ea087800eb838371d5da70538091e1148816296e 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -726,4 +726,9 @@ public final class MCUtil {
@@ -708,4 +708,9 @@ public final class MCUtil {
out.print(fileData);
}
}

View file

@ -70,10 +70,10 @@ index d53b34ba552771bf271131ce0a56ebb992ccc84c..a1b5e6b90fc93f83186cf3ebf3e15876
if (optional.isPresent()) {
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 9f8c0e10e42d233a8b74ee5a71fb8fb6ea8e7480..0d1065688b19ceca9440bc8bf2bf65910f03fa46 100644
index ea087800eb838371d5da70538091e1148816296e..ce0bf608b71cf492fc31e89a360ecd83fa5c23a6 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -628,7 +628,7 @@ public final class MCUtil {
@@ -610,7 +610,7 @@ public final class MCUtil {
WorldServer world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle();
PlayerChunkMap chunkMap = world.getChunkProvider().playerChunkMap;

View file

@ -97,7 +97,7 @@ index 4be93d12dbe12511628fd97af52d5cf78da17eaa..6dd4303c1c211ac4b0bb542ea96cc150
this.minecraftServer.getMethodProfiler().enter("keepAlive");
// Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 1c7aac029ae01afa127ca386278a4ff8520e3674..e11254d9e5a64ad02517e87d5c72a973affedfd9 100644
index 1c7aac029ae01afa127ca386278a4ff8520e3674..d7a9ec78db5994259bd6de289a8b4996349b2559 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -16,6 +16,7 @@ import java.util.Map;
@ -168,7 +168,7 @@ index 1c7aac029ae01afa127ca386278a4ff8520e3674..e11254d9e5a64ad02517e87d5c72a973
+ entityplayer, finalWorldserver, networkmanager, playerconnection,
+ nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName
+ );
+ playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair());
+ //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair());
+ };
+ });
+ }

View file

@ -553,10 +553,10 @@ index 74b868d7cec0260a10ca7718f48308f4ec54d56b..f832e7cdfc6741a932787f02754f1452
}
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 154b9f9a5696eaebb01dd59b7b27de75e95b501d..3061d856d52776ebc2eed6541238c8a760d7c536 100644
index d7a9ec78db5994259bd6de289a8b4996349b2559..6daca5c0ffd1d84f9a25cd106e8992a055dfb912 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -151,7 +151,7 @@ public abstract class PlayerList {
@@ -152,7 +152,7 @@ public abstract class PlayerList {
// CraftBukkit - getType()
// Spigot - view distance
networkmanager.queueImmunity = true; // Paper
@ -565,7 +565,7 @@ index 154b9f9a5696eaebb01dd59b7b27de75e95b501d..3061d856d52776ebc2eed6541238c8a7
entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName())));
playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
@@ -773,7 +773,7 @@ public abstract class PlayerList {
@@ -776,7 +776,7 @@ public abstract class PlayerList {
WorldData worlddata = worldserver.getWorldData();
entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getType(), WorldData.c(worldserver.getWorldData().getSeed()), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode()));
@ -574,7 +574,7 @@ index 154b9f9a5696eaebb01dd59b7b27de75e95b501d..3061d856d52776ebc2eed6541238c8a7
entityplayer1.spawnIn(worldserver);
entityplayer1.dead = false;
entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch));
@@ -1259,7 +1259,7 @@ public abstract class PlayerList {
@@ -1262,7 +1262,7 @@ public abstract class PlayerList {
public void a(int i) {
this.viewDistance = i;

View file

@ -52,7 +52,7 @@ index 88277d23c36696fdd5363e41a130c9a443fac2c0..b0b7544592981bcff22c8acee7230a21
}
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
index 53199595da71a25710bd1ff8ee2868ee63edc0e1..d5702b22f06ba4ad787fe2fcf788c3d4d147c927 100644
index 53199595da71a25710bd1ff8ee2868ee63edc0e1..37c44a89f28c44915fcae5a7e2c4797b1c123723 100644
--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java
+++ b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
@@ -33,7 +33,9 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
@ -62,7 +62,7 @@ index 53199595da71a25710bd1ff8ee2868ee63edc0e1..d5702b22f06ba4ad787fe2fcf788c3d4
- this.data.queueUpdate(i, ((NibbleArray) this.data.getUpdating(i)).b()); // Paper - avoid copying light data
+ NibbleArray updating = this.data.getUpdating(i); // Paper - pool nibbles
+ this.data.queueUpdate(i, new NibbleArray().markPoolSafe(updating.getCloneIfSet())); // Paper - avoid copying light data - pool safe clone
+ if (updating.cleaner != null) MCUtil.scheduleTask(2, updating.cleaner); // Paper - delay clean incase anything holding ref was still using it
+ if (updating.cleaner != null) MCUtil.scheduleTask(2, updating.cleaner, "Light Engine Release"); // Paper - delay clean incase anything holding ref was still using it
this.c();
}
@ -244,7 +244,7 @@ index 67c960292db9d99ac85b5d0dda50ae48ef942c1b..5e3efa1fa6c089df35971ce5c83da384
for (int i = 0; i < 16; ++i) {
System.arraycopy(this.a, 0, abyte, i * 128, 128);
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
index cd1ad45469aa163b9bc41774ae80adfa617fd97b..4b090757fceab6310f70ce34ba1041f890ddfd8f 100644
index cd1ad45469aa163b9bc41774ae80adfa617fd97b..27068f73a2b1fd97dc675ceb3f0eb07ac9e59437 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutLightUpdate.java
@@ -16,13 +16,42 @@ public class PacketPlayOutLightUpdate implements Packet<PacketListenerPlayOut> {
@ -270,7 +270,7 @@ index cd1ad45469aa163b9bc41774ae80adfa617fd97b..4b090757fceab6310f70ce34ba1041f8
+ cleaner1.run();
+ cleaner2.run();
+ }
+ });
+ }, "Light Packet Release");
+ }
+ }
+

View file

@ -90,7 +90,7 @@ index f617636a22167b06ac8073aa25efd8c7099155f0..0f40793f004639822b9d40521cd21ec5
return new BlockPosition(this.x << 4, 0, this.z << 4);
}
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..cbd7e82f22071f7453ce99f7a15d003653db227f 100644
index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..3a33d625cac39036df67aac81599fa1db7f808d4 100644
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
@@ -23,6 +23,7 @@ import java.util.concurrent.Executor;
@ -163,7 +163,7 @@ index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..cbd7e82f22071f7453ce99f7a15d0036
return removed; // CraftBukkit
}
@@ -182,6 +191,87 @@ public abstract class ChunkMapDistance {
@@ -182,6 +191,84 @@ public abstract class ChunkMapDistance {
this.addTicketAtLevel(tickettype, chunkcoordintpair, i, t0);
}
@ -182,24 +182,20 @@ index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..cbd7e82f22071f7453ce99f7a15d0036
+ AsyncCatcher.catchOp("ChunkMapDistance::addPriorityTicket");
+ long pair = coords.pair();
+ PlayerChunk updatingChunk = chunkMap.getUpdatingChunk(pair);
+ if (updatingChunk != null && updatingChunk.priorityBoost >= priority) {
+ return true;
+ }
+
+ boolean success;
+ if (!(success = updatePriorityTicket(coords, ticketType, priority))) {
+ Ticket<ChunkCoordIntPair> ticket = new Ticket<ChunkCoordIntPair>(ticketType, PRIORITY_TICKET_LEVEL, coords);
+ ticket.priority = priority;
+ success = this.addTicket(pair, ticket);
+ }
+
+ chunkMap.world.getChunkProvider().tickDistanceManager();
+ if (updatingChunk == null) {
+ updatingChunk = chunkMap.getUpdatingChunk(pair);
+ }
+ if (updatingChunk != null && updatingChunk.priorityBoost < priority) {
+ // May not be enqueued, enqueue it if not and tick distance manager
+ } else {
+ if (updatingChunk == null) {
+ updatingChunk = chunkMap.getUpdatingChunk(pair);
+ }
+ chunkMap.queueHolderUpdate(updatingChunk);
+ }
+ chunkMap.world.getChunkProvider().tickDistanceManager();
+
+ return success;
+ }
+
@ -211,6 +207,7 @@ index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..cbd7e82f22071f7453ce99f7a15d0036
+ for (Ticket<?> ticket : tickets) {
+ if (ticket.getTicketType() == type) {
+ // We only support increasing, not decreasing, too complicated
+ ticket.setCurrentTick(this.currentTick);
+ ticket.priority = Math.max(ticket.priority, priority);
+ return true;
+ }
@ -251,49 +248,31 @@ index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..cbd7e82f22071f7453ce99f7a15d0036
public <T> boolean addTicketAtLevel(TicketType<T> ticketType, ChunkCoordIntPair chunkcoordintpair, int level, T identifier) {
return this.addTicket(chunkcoordintpair.pair(), new Ticket<>(ticketType, level, identifier));
// CraftBukkit end
@@ -386,7 +476,32 @@ public abstract class ChunkMapDistance {
@@ -385,24 +472,25 @@ public abstract class ChunkMapDistance {
Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(i)); // Paper - no-tick view distance
if (flag1) {
ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
- ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
- ChunkMapDistance.this.m.execute(() -> {
+ // Paper start - smarter ticket delay based on frustum and distance
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> playersNearby = chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(i);
+ // delay ticket add based on distance if > 4, and penalize > 8 more
+ int delay = j < 4 ? 0 : (j > 8 ? 20 + j * 2 : j);
+ if (playersNearby != null && j < 4) {
+ Object[] backingSet = playersNearby.getBackingSet();
+ BlockPosition chunkPos = new ChunkCoordIntPair(i).asPosition();
+ double minDist = Double.MAX_VALUE;
+ for (int index = 0, len = backingSet.length; index < len; ++index) {
+ if (!(backingSet[index] instanceof EntityPlayer)) {
+ continue;
+ }
+ EntityPlayer player = (EntityPlayer) backingSet[index];
+ BlockPosition pointInFront = player.getPointInFront(3 * 16);
+
+ double dist = MCUtil.distanceSq(pointInFront, chunkPos);
+ if (dist < minDist && dist >= 4*4) {
+ minDist = dist;
+ }
+ }
+ if (minDist < Double.MAX_VALUE) {
+ delay += 10 + Math.sqrt(minDist)*3;
+ }
+ }
+ MCUtil.scheduleTask(delay, () -> {
+ // Paper end
if (this.c(this.c(i))) {
- if (this.c(this.c(i))) {
+ // Paper start - smarter ticket delay based on frustum and distance
+ scheduleChunkLoad(i, MinecraftServer.currentTick, (priority) -> {
+ ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
+ if (chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(i) != null && this.c(this.c(i))) { // Copy c(c()) stuff below
+ // Paper end
ChunkMapDistance.this.addTicket(i, ticket);
ChunkMapDistance.this.l.add(i);
@@ -397,12 +512,15 @@ public abstract class ChunkMapDistance {
});
} else {
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
}, i, false));
}
-
- });
}, i, () -> {
- return j;
+ int desired = j + chunkMap.getEffectiveViewDistance() >= j ? 20 : 30; // Paper - use less priority for no tick chunks
+ return Math.min(PlayerChunkMap.GOLDEN_TICKET, desired); // Paper - this is based on distance to player for priority,
+ // ensure new no tick tickets arent higher priority than high priority tickets...
}));
- }));
+ return priority; // Paper
+ })); });
} else {
ChunkMapDistance.this.k.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
ChunkMapDistance.this.m.execute(() -> {
@ -302,6 +281,90 @@ index 586a20fe5c77c2ad5fa26f337a94a16e21d8b5e2..cbd7e82f22071f7453ce99f7a15d0036
});
}, i, true));
}
@@ -410,6 +498,83 @@ public abstract class ChunkMapDistance {
}
+ // Paper start - smart scheduling of player tickets
+ public void scheduleChunkLoad(long i, long startTick, java.util.function.Consumer<Integer> task) {
+ long elapsed = MinecraftServer.currentTick - startTick;
+ PlayerChunk updatingChunk = chunkMap.getUpdatingChunk(i);
+ if ((updatingChunk != null && updatingChunk.isFullChunkReady()) || !this.c(this.c(i))) { // Copied from above
+ // no longer needed
+ task.accept(1);
+ return;
+ }
+
+ int desireDelay = 0;
+ double minDist = Double.MAX_VALUE;
+ com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<EntityPlayer> players = chunkMap.playerViewDistanceNoTickMap.getObjectsInRange(i);
+ ChunkCoordIntPair chunkPos = new ChunkCoordIntPair(i);
+ if (players != null) {
+ BlockPosition.PooledBlockPosition pos = BlockPosition.PooledBlockPosition.acquire();
+ Object[] backingSet = players.getBackingSet();
+
+ BlockPosition blockPos = chunkPos.asPosition();
+
+ boolean isFront = false;
+ for (int index = 0, len = backingSet.length; index < len; ++index) {
+ if (!(backingSet[index] instanceof EntityPlayer)) {
+ continue;
+ }
+ EntityPlayer player = (EntityPlayer) backingSet[index];
+ BlockPosition pointInFront = player.getPointInFront(3 * 16).add(0, (int) -player.locY(), 0);
+ pos.setValues(((int) player.locX() >> 4) << 4, 0, ((int) player.locZ() >> 4) << 4);
+ double frontDist = MCUtil.distanceSq(pointInFront, blockPos);
+ double center = MCUtil.distanceSq(pos, blockPos);
+ double dist = Math.min(frontDist, center);
+ if (!isFront) {
+ BlockPosition pointInBack = player.getPointInFront(3 * 16 * -1).add(0, (int) -player.locY(), 0);
+ double backDist = MCUtil.distanceSq(pointInBack, blockPos);
+ if (frontDist < backDist) {
+ isFront = true;
+ }
+ }
+ if (dist < minDist) {
+ minDist = dist;
+ }
+ }
+ pos.close();
+ if (minDist < Double.MAX_VALUE) {
+ minDist = Math.sqrt(minDist) / 16;
+ if (minDist > 5) {
+ desireDelay += ((isFront ? 15 : 30) * 20) * (minDist / 32);
+ }
+ }
+ } else {
+ desireDelay = 1;
+ }
+ long delay = desireDelay - elapsed;
+ if (delay <= 0 && minDist > 4 && minDist < Double.MAX_VALUE) {
+ boolean hasAnyNeighbor = false;
+ for (int x = -1; x <= 1; x++) {
+ for (int z = -1; z <= 1; z++) {
+ if (x == 0 && z == 0) continue;
+ long pair = new ChunkCoordIntPair(chunkPos.x + x, chunkPos.z + z).pair();
+ PlayerChunk neighbor = chunkMap.getUpdatingChunk(pair);
+ if (neighbor != null && neighbor.isFullChunkReady()) {
+ hasAnyNeighbor = true;
+ }
+ }
+ }
+ if (!hasAnyNeighbor) {
+ delay += 10;
+ }
+ }
+ if (delay <= 0) {
+ task.accept(Math.min(PlayerChunkMap.GOLDEN_TICKET, minDist < Double.MAX_VALUE ? (int) minDist : 15));
+ } else {
+ MCUtil.scheduleTask((int) Math.min(delay, 20), () -> scheduleChunkLoad(i, startTick, task), "Player Ticket Delayer");
+ }
+ }
+ // Paper end
+
@Override
public void a() {
super.a();
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 7a275bf3260f9fbefc41883c5ebdc1eb2196daf0..a0e4571522d2b64a687c34ef2ba12361177630e4 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
@ -409,10 +472,10 @@ index 07a6fc3d88e7d44bfab7f3d6a0eef7dc132ab422..c88177b77607519453bb349a8e960d22
for (int i = 0; i < this.inventory.getSize(); ++i) {
ItemStack itemstack = this.inventory.getItem(i);
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 0d1065688b19ceca9440bc8bf2bf65910f03fa46..8a349964578e07e5ed13f801c57de68459220da9 100644
index ce0bf608b71cf492fc31e89a360ecd83fa5c23a6..87d58002116f361d8255d79fc0dbd1200f442168 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -684,6 +684,7 @@ public final class MCUtil {
@@ -666,6 +666,7 @@ public final class MCUtil {
chunkData.addProperty("x", playerChunk.location.x);
chunkData.addProperty("z", playerChunk.location.z);
chunkData.addProperty("ticket-level", playerChunk.getTicketLevel());
@ -676,7 +739,7 @@ index aeca6b2b9d5d73aeb6dc639b5cad2f2533a2de44..04dcb79c6033f1dec62c5df49937a4ef
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a003b9ea0 100644
index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..be4078fc0fc67ab0fd281e3b7781fe1b22bde809 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -50,6 +50,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
@ -721,7 +784,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
this.playerViewDistanceNoTickMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets);
this.playerViewDistanceBroadcastMap = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets,
(EntityPlayer player, int rangeX, int rangeZ, int currPosX, int currPosZ, int prevPosX, int prevPosZ,
@@ -410,6 +415,99 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -410,6 +415,102 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
});
// Paper end - no-tick view distance
}
@ -732,6 +795,9 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
+ return; // unloaded
+ }
+ chunkDistanceManager.pendingChunkUpdates.add(playerchunk);
+ if (!chunkDistanceManager.pollingPendingChunkUpdates) {
+ world.getChunkProvider().tickDistanceManager();
+ }
+ };
+ if (MCUtil.isMainThread()) {
+ // We can't use executor here because it will not execute tasks if its currently in the middle of executing tasks...
@ -741,8 +807,8 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
+ }
+ }
+
+ public boolean isUnloading(PlayerChunk playerchunk) {
+ return playerchunk == null || MCUtil.getChunkStatus(playerchunk) == null || unloadQueue.contains(playerchunk.location.pair());
+ private boolean isUnloading(PlayerChunk playerchunk) {
+ return playerchunk == null || unloadQueue.contains(playerchunk.location.pair());
+ }
+
+ public void checkHighPriorityChunks(EntityPlayer player) {
@ -821,7 +887,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
public void updatePlayerMobTypeMap(Entity entity) {
if (!this.world.paperConfig.perPlayerMobSpawns) {
@@ -539,6 +637,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -539,6 +640,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
List<CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>>> list = Lists.newArrayList();
int j = chunkcoordintpair.x;
int k = chunkcoordintpair.z;
@ -829,7 +895,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
for (int l = -i; l <= i; ++l) {
for (int i1 = -i; i1 <= i; ++i1) {
@@ -557,6 +656,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -557,6 +659,14 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
ChunkStatus chunkstatus = (ChunkStatus) intfunction.apply(j1);
CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> completablefuture = playerchunk.a(chunkstatus, this);
@ -844,7 +910,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
list.add(completablefuture);
}
@@ -1022,14 +1129,22 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1022,14 +1132,22 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
};
CompletableFuture<NBTTagCompound> chunkSaveFuture = this.world.asyncChunkTaskManager.getChunkSaveFuture(chunkcoordintpair.x, chunkcoordintpair.z);
@ -872,7 +938,7 @@ index 0aa14bfca6e1845eb6e9f5bd4e0e36335fa7f532..4b748bf34b4f99d665cae6aa01000c4a
return ret;
// Paper end
}
@@ -1158,7 +1273,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1158,7 +1276,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
long i = playerchunk.i().pair();
playerchunk.getClass();
@ -894,10 +960,10 @@ index 7a8397815a5b7f79f3e3a0348aeedf63fe879f8f..0d6e0f2ddaa85c04e626980591e9a78a
protected Ticket(TicketType<T> tickettype, int i, T t0) {
this.a = tickettype;
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
index 8055f5998213ab1c6c10d03d88d2b14d220a5e40..24ec5d77ca7fdf12585c1bb7442554380f0c1918 100644
index d7b9d9fd3a3b607278a3d72b0b306b0be2aa30ad..6fd852db6bcfbfbf84ec2acf6d23b08a6051165c 100644
--- a/src/main/java/net/minecraft/server/TicketType.java
+++ b/src/main/java/net/minecraft/server/TicketType.java
@@ -23,6 +23,8 @@ public class TicketType<T> {
@@ -24,6 +24,8 @@ public class TicketType<T> {
public static final TicketType<org.bukkit.plugin.Plugin> PLUGIN_TICKET = a("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit
public static final TicketType<Long> FUTURE_AWAIT = a("future_await", Long::compareTo); // Paper
public static final TicketType<Long> ASYNC_LOAD = a("async_load", Long::compareTo); // Paper

View file

@ -11,10 +11,10 @@ This will drastically cut down on packet sending cost for worlds with
lots of players in them.
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 3061d856d52776ebc2eed6541238c8a760d7c536..7bb46cc7c6fefc04a8faf7766f31e4780a9c7e10 100644
index 6daca5c0ffd1d84f9a25cd106e8992a055dfb912..c03395ce824ec1305b3cabb63343922d32a02b85 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -1027,11 +1027,30 @@ public abstract class PlayerList {
@@ -1030,11 +1030,30 @@ public abstract class PlayerList {
world = (WorldServer) entityhuman.world;
}

View file

@ -54,7 +54,7 @@ index 04dcb79c6033f1dec62c5df49937a4ef067a2cb8..f8820f24075e7f42f67426fc9ecf5238
// Paper start - no-tick view distance
public final Chunk getSendingChunk() {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 4b748bf34b4f99d665cae6aa01000c4a003b9ea0..15028f5d9bab0d4ad26ca70b954aeff0634bc579 100644
index be4078fc0fc67ab0fd281e3b7781fe1b22bde809..9914f6dd4a7ea9b5ed1f2b25707f18b00ce69dec 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -88,6 +88,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -81,7 +81,7 @@ index 4b748bf34b4f99d665cae6aa01000c4a003b9ea0..15028f5d9bab0d4ad26ca70b954aeff0
ThreadedMailbox<Runnable> threadedmailbox = ThreadedMailbox.a(executor, "worldgen");
iasynctaskhandler.getClass();
@@ -704,7 +714,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -707,7 +717,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return either.mapLeft((list) -> {
return (Chunk) list.get(list.size() / 2);
});
@ -90,7 +90,7 @@ index 4b748bf34b4f99d665cae6aa01000c4a003b9ea0..15028f5d9bab0d4ad26ca70b954aeff0
}
@Nullable
@@ -1070,7 +1080,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1073,7 +1083,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return this.b(playerchunk, chunkstatus);
}
}
@ -99,7 +99,7 @@ index 4b748bf34b4f99d665cae6aa01000c4a003b9ea0..15028f5d9bab0d4ad26ca70b954aeff0
}
}
@@ -1181,6 +1191,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -1184,6 +1194,12 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
return CompletableFuture.completedFuture(Either.right(playerchunk_failure));
});
}, (runnable) -> {

View file

@ -852,7 +852,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
}
}
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
index d5702b22f06ba4ad787fe2fcf788c3d4d147c927..5e397b9195b2b86c76c0c7cc4102ab4eef46071a 100644
index 37c44a89f28c44915fcae5a7e2c4797b1c123723..53c204455c3800b4fe399ce6261b0495eea4d003 100644
--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java
+++ b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
@@ -43,6 +43,25 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
@ -1200,10 +1200,10 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..72cc711d6c2645aed44f208ee44f8702
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 15028f5d9bab0d4ad26ca70b954aeff0634bc579..580721583c274f60ac70e2b05ab8d69a556df5f3 100644
index 9914f6dd4a7ea9b5ed1f2b25707f18b00ce69dec..c58c38c8359044c814c0b724389956cae9f63b9f 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -627,6 +627,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@@ -630,6 +630,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
// Paper end
}

View file

@ -35,7 +35,7 @@ index 5c8a946d5c895fc2622c7df656cc462c58104cf7..d64e996dde2c7665119c4bc1d907c40a
+ }
}
diff --git a/src/main/java/net/minecraft/server/ChunkMapDistance.java b/src/main/java/net/minecraft/server/ChunkMapDistance.java
index cbd7e82f22071f7453ce99f7a15d003653db227f..01e8b9bd3c3aded949edbae4c8bd1dc9d1637df2 100644
index 3a33d625cac39036df67aac81599fa1db7f808d4..7eb14c2e3a13a9d2d6c5e699eca3ce60b50e9188 100644
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
@@ -176,6 +176,27 @@ public abstract class ChunkMapDistance {
@ -100,10 +100,10 @@ index 0d6e0f2ddaa85c04e626980591e9a78ac27fb42d..c79aa4a80a8a2288f7a50466abd677f3
return j != 0L && i - this.d > j;
}
diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java
index 24ec5d77ca7fdf12585c1bb7442554380f0c1918..02dce9e6da17eb78d80f83b798cc94ddfac734d7 100644
index 6fd852db6bcfbfbf84ec2acf6d23b08a6051165c..5c789b25f1df2eae8ea8ceb4ba977ba336fe6d5e 100644
--- a/src/main/java/net/minecraft/server/TicketType.java
+++ b/src/main/java/net/minecraft/server/TicketType.java
@@ -25,6 +25,7 @@ public class TicketType<T> {
@@ -26,6 +26,7 @@ public class TicketType<T> {
public static final TicketType<Long> ASYNC_LOAD = a("async_load", Long::compareTo); // Paper
public static final TicketType<ChunkCoordIntPair> PRIORITY = a("priority", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper
public static final TicketType<ChunkCoordIntPair> URGENT = a("urgent", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper