From b2d81e21c53a8d073155dbf17c8a8986ef56001e Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 9 Jun 2020 03:17:25 -0400 Subject: [PATCH] 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. --- Spigot-Server-Patches/0004-MC-Utils.patch | 218 ++++++++++++++++-- Spigot-Server-Patches/0009-Timings-v2.patch | 51 ++-- .../0022-Optimize-TileEntity-Ticking.patch | 8 +- .../0054-Add-exception-reporting-event.patch | 6 +- ...e-CraftScheduler-Async-Task-Debugger.patch | 8 +- .../0154-Basic-PlayerProfile-API.patch | 6 +- .../0202-Improved-Async-Task-Scheduler.patch | 34 +-- ...arseException-in-Entity-and-TE-names.patch | 4 +- .../0377-Chunk-debug-command.patch | 4 +- ...90-Asynchronous-chunk-IO-and-loading.patch | 4 +- ...hunkMap-memory-use-for-visibleChunks.patch | 4 +- ...Load-Chunks-for-Login-Asynchronously.patch | 4 +- ...No-Tick-view-distance-implementation.patch | 8 +- ...ze-NibbleArray-to-use-pooled-buffers.patch | 8 +- ...k-Priority-Urgency-System-for-Chunks.patch | 188 ++++++++++----- ...-packets-to-nearby-locations-sounds-.patch | 4 +- ...mprove-Chunk-Status-Transition-Speed.patch | 8 +- .../0537-Optimize-Light-Engine.patch | 6 +- ...unk-Unloads-based-on-Player-Movement.patch | 6 +- 19 files changed, 417 insertions(+), 162 deletions(-) diff --git a/Spigot-Server-Patches/0004-MC-Utils.patch b/Spigot-Server-Patches/0004-MC-Utils.patch index e8581590a0..5d646fa432 100644 --- a/Spigot-Server-Patches/0004-MC-Utils.patch +++ b/Spigot-Server-Patches/0004-MC-Utils.patch @@ -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 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 diff --git a/Spigot-Server-Patches/0009-Timings-v2.patch b/Spigot-Server-Patches/0009-Timings-v2.patch index 3e06a6ec27..918dc84a43 100644 --- a/Spigot-Server-Patches/0009-Timings-v2.patch +++ b/Spigot-Server-Patches/0009-Timings-v2.patch @@ -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; } diff --git a/Spigot-Server-Patches/0022-Optimize-TileEntity-Ticking.patch b/Spigot-Server-Patches/0022-Optimize-TileEntity-Ticking.patch index 8d64b6a092..a6d738ce95 100644 --- a/Spigot-Server-Patches/0022-Optimize-TileEntity-Ticking.patch +++ b/Spigot-Server-Patches/0022-Optimize-TileEntity-Ticking.patch @@ -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; diff --git a/Spigot-Server-Patches/0054-Add-exception-reporting-event.patch b/Spigot-Server-Patches/0054-Add-exception-reporting-event.patch index c89d13d178..ccf79bfb40 100644 --- a/Spigot-Server-Patches/0054-Add-exception-reporting-event.patch +++ b/Spigot-Server-Patches/0054-Add-exception-reporting-event.patch @@ -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) { diff --git a/Spigot-Server-Patches/0141-Remove-CraftScheduler-Async-Task-Debugger.patch b/Spigot-Server-Patches/0141-Remove-CraftScheduler-Async-Task-Debugger.patch index f44fe4accf..a602785ad5 100644 --- a/Spigot-Server-Patches/0141-Remove-CraftScheduler-Async-Task-Debugger.patch +++ b/Spigot-Server-Patches/0141-Remove-CraftScheduler-Async-Task-Debugger.patch @@ -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() { diff --git a/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch b/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch index 2f7e36cb9f..59a1ff797a 100644 --- a/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch +++ b/Spigot-Server-Patches/0154-Basic-PlayerProfile-API.patch @@ -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() { @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 getActiveWorkers() { @@ -291,7 +291,7 @@ index 8c48130db03e1baffa341222caa6a82b29525671..b116a415958c35951c738faf0b3f413b final ArrayList workers = new ArrayList(); 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 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 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; diff --git a/Spigot-Server-Patches/0301-Catch-JsonParseException-in-Entity-and-TE-names.patch b/Spigot-Server-Patches/0301-Catch-JsonParseException-in-Entity-and-TE-names.patch index 234005a4d7..0547b7b897 100644 --- a/Spigot-Server-Patches/0301-Catch-JsonParseException-in-Entity-and-TE-names.patch +++ b/Spigot-Server-Patches/0301-Catch-JsonParseException-in-Entity-and-TE-names.patch @@ -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; } } diff --git a/Spigot-Server-Patches/0377-Chunk-debug-command.patch b/Spigot-Server-Patches/0377-Chunk-debug-command.patch index 26c5526246..e327853d6c 100644 --- a/Spigot-Server-Patches/0377-Chunk-debug-command.patch +++ b/Spigot-Server-Patches/0377-Chunk-debug-command.patch @@ -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; } diff --git a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch index 06da174caf..974ec152b4 100644 --- a/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0390-Asynchronous-chunk-IO-and-loading.patch @@ -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); } } diff --git a/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch b/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch index 246d9a783c..dae3153824 100644 --- a/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch +++ b/Spigot-Server-Patches/0456-Optimize-PlayerChunkMap-memory-use-for-visibleChunks.patch @@ -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; diff --git a/Spigot-Server-Patches/0485-Load-Chunks-for-Login-Asynchronously.patch b/Spigot-Server-Patches/0485-Load-Chunks-for-Login-Asynchronously.patch index 00a3f8167b..b2205b212d 100644 --- a/Spigot-Server-Patches/0485-Load-Chunks-for-Login-Asynchronously.patch +++ b/Spigot-Server-Patches/0485-Load-Chunks-for-Login-Asynchronously.patch @@ -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()); + }; + }); + } diff --git a/Spigot-Server-Patches/0504-No-Tick-view-distance-implementation.patch b/Spigot-Server-Patches/0504-No-Tick-view-distance-implementation.patch index 9b24616353..9613853345 100644 --- a/Spigot-Server-Patches/0504-No-Tick-view-distance-implementation.patch +++ b/Spigot-Server-Patches/0504-No-Tick-view-distance-implementation.patch @@ -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; diff --git a/Spigot-Server-Patches/0521-Optimize-NibbleArray-to-use-pooled-buffers.patch b/Spigot-Server-Patches/0521-Optimize-NibbleArray-to-use-pooled-buffers.patch index 6345ae7819..bbd03eef7a 100644 --- a/Spigot-Server-Patches/0521-Optimize-NibbleArray-to-use-pooled-buffers.patch +++ b/Spigot-Server-Patches/0521-Optimize-NibbleArray-to-use-pooled-buffers.patch @@ -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 { @@ -270,7 +270,7 @@ index cd1ad45469aa163b9bc41774ae80adfa617fd97b..4b090757fceab6310f70ce34ba1041f8 + cleaner1.run(); + cleaner2.run(); + } -+ }); ++ }, "Light Packet Release"); + } + } + diff --git a/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch b/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch index aa630f58ab..c395dc34b0 100644 --- a/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch +++ b/Spigot-Server-Patches/0528-Implement-Chunk-Priority-Urgency-System-for-Chunks.patch @@ -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 ticket = new Ticket(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 boolean addTicketAtLevel(TicketType 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 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 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 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>> 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> 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 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 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 { +@@ -24,6 +24,8 @@ public class TicketType { public static final TicketType PLUGIN_TICKET = a("plugin_ticket", (plugin1, plugin2) -> plugin1.getClass().getName().compareTo(plugin2.getClass().getName())); // CraftBukkit public static final TicketType FUTURE_AWAIT = a("future_await", Long::compareTo); // Paper public static final TicketType ASYNC_LOAD = a("async_load", Long::compareTo); // Paper diff --git a/Spigot-Server-Patches/0530-Optimize-sending-packets-to-nearby-locations-sounds-.patch b/Spigot-Server-Patches/0530-Optimize-sending-packets-to-nearby-locations-sounds-.patch index b7c2c4ee8b..5cd96e93a6 100644 --- a/Spigot-Server-Patches/0530-Optimize-sending-packets-to-nearby-locations-sounds-.patch +++ b/Spigot-Server-Patches/0530-Optimize-sending-packets-to-nearby-locations-sounds-.patch @@ -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; } diff --git a/Spigot-Server-Patches/0532-Improve-Chunk-Status-Transition-Speed.patch b/Spigot-Server-Patches/0532-Improve-Chunk-Status-Transition-Speed.patch index 3ac7e510d7..b75def9aed 100644 --- a/Spigot-Server-Patches/0532-Improve-Chunk-Status-Transition-Speed.patch +++ b/Spigot-Server-Patches/0532-Improve-Chunk-Status-Transition-Speed.patch @@ -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 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) -> { diff --git a/Spigot-Server-Patches/0537-Optimize-Light-Engine.patch b/Spigot-Server-Patches/0537-Optimize-Light-Engine.patch index 828ceb980a..f56ae3560f 100644 --- a/Spigot-Server-Patches/0537-Optimize-Light-Engine.patch +++ b/Spigot-Server-Patches/0537-Optimize-Light-Engine.patch @@ -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 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 { +@@ -26,6 +26,7 @@ public class TicketType { public static final TicketType ASYNC_LOAD = a("async_load", Long::compareTo); // Paper public static final TicketType PRIORITY = a("priority", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper public static final TicketType URGENT = a("urgent", Comparator.comparingLong(ChunkCoordIntPair::pair), 300); // Paper