Clean up thread pool usage (#11681)

Using an unbound LinkedBlockingQueue means you *have* to set core and max core thread pool size the same, as they will never go above the minimum pool size by just passing them through. So this fixes the async command executor pool to actually use 2 threads, and also cleans up other usage to be explicitly "fixed" thread pool sizes, and splits off one more in Minecraft's Util class
This commit is contained in:
Nassim Jahnke 2024-11-29 17:07:35 +01:00 committed by GitHub
parent 9953384d89
commit 64828f3a60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 96 additions and 52 deletions

View file

@ -4844,10 +4844,10 @@ index 0000000000000000000000000000000000000000..197224e31175252d8438a8df585bbb65
+}
diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41cea31c4d
index 0000000000000000000000000000000000000000..a4ac34ebb58a404f4fca7e763e61d4ab05ee3af4
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
@@ -0,0 +1,209 @@
@@ -0,0 +1,205 @@
+package io.papermc.paper.util;
+
+import com.google.common.collect.Collections2;
@ -4861,9 +4861,8 @@ index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Function;
@ -4888,13 +4887,10 @@ index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41
+ run.run();
+ }
+ };
+ public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor(
+ 2, 2, 60L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(),
+ new ThreadFactoryBuilder()
+ .setNameFormat("Paper Async Task Handler Thread - %1$d")
+ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER))
+ .build()
+ public static final ExecutorService ASYNC_EXECUTOR = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder()
+ .setNameFormat("Paper Async Task Handler Thread - %1$d")
+ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER))
+ .build()
+ );
+
+ private MCUtil() {
@ -5029,7 +5025,7 @@ index 0000000000000000000000000000000000000000..9d97c9afa31bed6d2e6b7778bfe4cc41
+ }
+
+ public static void scheduleAsyncTask(Runnable run) {
+ asyncExecutor.execute(run);
+ ASYNC_EXECUTOR.execute(run);
+ }
+
+ public static <T> ResourceKey<T> toResourceKey(
@ -5216,15 +5212,15 @@ index 3e5a85a7ad6149b04622c254fbc2e174896a4128..3f662692ed4846e026a9d48595e7b3b2
+
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 8e16bc7da15824723f1d7d4bff87fac181978500..709330ca9caa82a6de71767b3d5c32f97ea1d68b 100644
index 8e16bc7da15824723f1d7d4bff87fac181978500..1b6cf839450cc69bd3cda6d874656c5345b0ac51 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -988,6 +988,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1);
}
// Spigot start
+ io.papermc.paper.util.MCUtil.asyncExecutor.shutdown(); // Paper
+ try { io.papermc.paper.util.MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
+ io.papermc.paper.util.MCUtil.ASYNC_EXECUTOR.shutdown(); // Paper
+ try { io.papermc.paper.util.MCUtil.ASYNC_EXECUTOR.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
+ } catch (java.lang.InterruptedException ignored) {} // Paper
if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
MinecraftServer.LOGGER.info("Saving usercache.json");

View file

@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..b60f59cf5cc8eb84a6055b7861857dec
+ }
+}
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..bf2833c92eca6491699b4a89410e4e46b5bbe4d1 100644
index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..dbf79a018260a006bf5d16608b35bcbea9adb963 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -92,7 +92,7 @@ public class Util {
@ -78,7 +78,7 @@ index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..bf2833c92eca6491699b4a89410e4e46
- AtomicInteger atomicInteger = new AtomicInteger(1);
- executorService = new ForkJoinPool(i, pool -> {
- final String string2 = "Worker-" + name + "-" + atomicInteger.getAndIncrement();
+ executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<>(), target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier));
+ executorService = Executors.newFixedThreadPool(i, target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier));
+ }
+ /* final String string2 = "Worker-" + name + "-" + atomicInteger.getAndIncrement();
ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(pool) {
@ -94,7 +94,7 @@ index 8cac2075077b1d9c2b01e09c99780ff9e204abb2..bf2833c92eca6491699b4a89410e4e46
return new TracingExecutor(executorService);
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c4d8918a7accbe5eb3035b4ec3b423f30c613d60..b54c1ecf3384fba741fa6334caee498b83887508 100644
index af20a16e18673a629fc3033d8e7e07eba855b1c7..2a4f8075867a302afd98bdf9ac8b11622c29082d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -332,6 +332,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -9,27 +9,22 @@ commands if the server is restarting. Using the default async pool caused issues
due to the shutdown logic generally being much later.
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..e812cc865baaa1ee03872f7969ee98600b82483b 100644
index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..34564f4118eab9e95176cb4ff4bc93fbe97d9b6b 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -455,6 +455,24 @@ public class Commands {
@@ -455,6 +455,19 @@ public class Commands {
if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot
// CraftBukkit start
// Register Vanilla commands into builtRoot as before
+ // Paper start - Perf: Async command map building
+ COMMAND_SENDING_POOL.execute(() -> {
+ this.sendAsync(player);
+ });
+ COMMAND_SENDING_POOL.execute(() -> this.sendAsync(player));
+ }
+
+ public static final java.util.concurrent.ThreadPoolExecutor COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor(
+ 0, 2, 60L, java.util.concurrent.TimeUnit.SECONDS,
+ new java.util.concurrent.LinkedBlockingQueue<>(),
+ public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = java.util.concurrent.Executors.newFixedThreadPool(2,
+ new com.google.common.util.concurrent.ThreadFactoryBuilder()
+ .setNameFormat("Paper Async Command Builder Thread Pool - %1$d")
+ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER))
+ .build(),
+ new java.util.concurrent.ThreadPoolExecutor.DiscardPolicy()
+ .build()
+ );
+
+ private void sendAsync(ServerPlayer player) {
@ -37,7 +32,7 @@ index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..e812cc865baaa1ee03872f7969ee9860
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
RootCommandNode vanillaRoot = new RootCommandNode();
@@ -472,7 +490,14 @@ public class Commands {
@@ -472,7 +485,14 @@ public class Commands {
for (CommandNode node : rootcommandnode.getChildren()) {
bukkit.add(node.getName());
}
@ -53,7 +48,7 @@ index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..e812cc865baaa1ee03872f7969ee9860
event.getPlayer().getServer().getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 13aa191235ac6bb1d00d89ae29c750595cc6be78..0f1a7b649d398a875b57746530242e3ced595bfd 100644
index 9a9291282f7ec99be9badf8b32fab5f0ea0f1037..feb45369b41b597fd603c12f3da23759923b6a6d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -944,6 +944,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -87,10 +87,10 @@ index 4d5f1dd1c3bd742b1bc5e3914101a699041caa7e..5316f148f3f9128690f019d544e462b0
public boolean hasPermission(int level) {
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index e812cc865baaa1ee03872f7969ee98600b82483b..c847fbdb6f52386570eb4c070fcc01d39cc52151 100644
index 34564f4118eab9e95176cb4ff4bc93fbe97d9b6b..c2c8193a3b3f7a224b05a09cd65108860aaae814 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -491,6 +491,7 @@ public class Commands {
@@ -486,6 +486,7 @@ public class Commands {
bukkit.add(node.getName());
}
// Paper start - Perf: Async command map building
@ -98,7 +98,7 @@ index e812cc865baaa1ee03872f7969ee98600b82483b..c847fbdb6f52386570eb4c070fcc01d3
net.minecraft.server.MinecraftServer.getServer().execute(() -> {
runSync(player, bukkit, rootcommandnode);
});
@@ -498,6 +499,7 @@ public class Commands {
@@ -493,6 +494,7 @@ public class Commands {
private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
// Paper end - Perf: Async command map building
@ -106,7 +106,7 @@ index e812cc865baaa1ee03872f7969ee98600b82483b..c847fbdb6f52386570eb4c070fcc01d3
PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit));
event.getPlayer().getServer().getPluginManager().callEvent(event);
@@ -516,6 +518,11 @@ public class Commands {
@@ -511,6 +513,11 @@ public class Commands {
while (iterator.hasNext()) {
CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next();

View file

@ -2068,7 +2068,7 @@ index fc0c60b22844ed010aede2fa125b9fa440d3de80..3549ffea451b932602efb113844ba21a
public org.bukkit.command.CommandSender getBukkitSender() {
return this.source.getBukkitSender(this);
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187feb694761 100644
index 26bc8d7075f8a9c411776ab91aeddcd776d21348..2fc5651d1546fd4bb10b0617540e906f483cb36c 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -159,7 +159,7 @@ public class Commands {
@ -2135,7 +2135,7 @@ index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187f
StackTraceElement[] astacktraceelement = exception.getStackTrace();
for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) {
@@ -478,13 +497,7 @@ public class Commands {
@@ -473,13 +492,7 @@ public class Commands {
private void sendAsync(ServerPlayer player) {
// Paper end - Perf: Async command map building
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
@ -2150,7 +2150,7 @@ index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187f
RootCommandNode<SharedSuggestionProvider> rootcommandnode = new RootCommandNode();
map.put(this.dispatcher.getRoot(), rootcommandnode);
@@ -518,6 +531,7 @@ public class Commands {
@@ -513,6 +526,7 @@ public class Commands {
}
private void fillUsableCommands(CommandNode<CommandSourceStack> tree, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) {
@ -2158,7 +2158,7 @@ index fe9f638db3525893beed565ef9b7ac2fc76318bd..b1571c162fd8ab7239a7f4aafea5187f
Iterator iterator = tree.getChildren().iterator();
while (iterator.hasNext()) {
@@ -531,6 +545,42 @@ public class Commands {
@@ -526,6 +540,42 @@ public class Commands {
if (commandnode2.canUse(source)) {
ArgumentBuilder argumentbuilder = commandnode2.createBuilder(); // CraftBukkit - decompile error
@ -2218,7 +2218,7 @@ index 55484826fc5ddd04ae024e25a0251796d7fa9c28..237e4f7b24908e9ade9a483eb7ae05fa
Component component = message.resolveComponent(commandSourceStack);
CommandSigningContext commandSigningContext = commandSourceStack.getSigningContext();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 95786d2e1a8ac0fdbe8d449b3f100ac0512ee21e..b13b3991292ab96542ba390f3e8e3ff0d7529c44 100644
index 9c1e1c049db55e73851e3d513cba25027bd0c3b4..ab1a2c4272c4c84743ff501bb35816d35c9d4c94 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -316,7 +316,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -37,10 +37,10 @@ index 3549ffea451b932602efb113844ba21a7bc72371..13bd145b1e8006a53c22f5dc0c78f29b
+ // Paper end - tell clients to ask server for suggestions for EntityArguments
}
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index b1571c162fd8ab7239a7f4aafea5187feb694761..1e7b99a82184f73aa31cb2e0d4e52a806240926f 100644
index 2fc5651d1546fd4bb10b0617540e906f483cb36c..f58275101fd5671bab0aa66875c989e568384647 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -534,6 +534,7 @@ public class Commands {
@@ -529,6 +529,7 @@ public class Commands {
resultNodes.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below
Iterator iterator = tree.getChildren().iterator();
@ -48,7 +48,7 @@ index b1571c162fd8ab7239a7f4aafea5187feb694761..1e7b99a82184f73aa31cb2e0d4e52a80
while (iterator.hasNext()) {
CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next();
// Paper start - Brigadier API
@@ -596,6 +597,12 @@ public class Commands {
@@ -591,6 +592,12 @@ public class Commands {
if (requiredargumentbuilder.getSuggestionsProvider() != null) {
requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider()));

View file

@ -0,0 +1,53 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nassim Jahnke <nassim@njahnke.dev>
Date: Thu, 28 Nov 2024 10:35:58 +0100
Subject: [PATCH] Separate dimensiondata executor
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 276ad77ecb274b6cd454d0f92457964a8eaa5824..1360aa8202542d3d0f32247f1123575fc2c38ff1 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -94,6 +94,7 @@ public class Util {
private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
private static final TracingExecutor BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - Perf: add priority
private static final TracingExecutor IO_POOL = makeIoExecutor("IO-Worker-", false);
+ public static final TracingExecutor DIMENSION_DATA_IO_POOL = makeExtraIoExecutor("Dimension-Data-IO-Worker-"); // Paper - Separate dimension data IO pool
private static final TracingExecutor DOWNLOAD_POOL = makeIoExecutor("Download-", true);
// Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {
@@ -260,6 +261,21 @@ public class Util {
}));
}
+ // Paper start - Separate dimension data IO pool
+ private static TracingExecutor makeExtraIoExecutor(String namePrefix) {
+ AtomicInteger atomicInteger = new AtomicInteger(1);
+ return new TracingExecutor(Executors.newFixedThreadPool(4, runnable -> {
+ Thread thread = new Thread(runnable);
+ String string2 = namePrefix + atomicInteger.getAndIncrement();
+ TracyClient.setThreadName(string2, namePrefix.hashCode());
+ thread.setName(string2);
+ thread.setDaemon(false);
+ thread.setUncaughtExceptionHandler(Util::onThreadException);
+ return thread;
+ }));
+ }
+ // Paper end - Separate dimension data IO pool
+
public static void throwAsRuntime(Throwable t) {
throw t instanceof RuntimeException ? (RuntimeException)t : new RuntimeException(t);
}
diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java
index d16f124e0371ce943298c8d7d9bfac21e98cf885..8212f2dfba5c2eee5a823b5217fb43dc870d228a 100644
--- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java
+++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java
@@ -155,7 +155,7 @@ public class DimensionDataStorage implements AutoCloseable {
} catch (IOException var3) {
LOGGER.error("Could not save data to {}", path.getFileName(), var3);
}
- }, Util.ioPool());
+ }, Util.DIMENSION_DATA_IO_POOL); // Paper - Separate dimension data IO pool
}
public void saveAndJoin() {

View file

@ -23410,7 +23410,7 @@ index fc6ce3485dc890f5105a37fe3e344a1460867556..e114e687f2f4503546687fd6792226a6
DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, worldLoader.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::createFromGameruleRadius);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index e18692ad6bdbc8bc2df605833501b1ad888b8b7d..ed1f8c735bf9f13014112056b85ff195b02ee76e 100644
index 57b242a4a1de49e8869e8ec83e74d60d877a4003..9cb435573d0b1bdf5488bd5b9cef5d2aba6a1c2d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -204,7 +204,7 @@ import org.bukkit.event.server.ServerLoadEvent;

View file

@ -117,7 +117,7 @@ index e114e687f2f4503546687fd6792226a643af8793..90ca25c4aaf92a5639839a7cdaee2ffc
/* CraftBukkit start - Replace everything
OptionParser optionparser = new OptionParser();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index ed1f8c735bf9f13014112056b85ff195b02ee76e..b29dbab3c26c078eb993183d808149d958857f3a 100644
index 9cb435573d0b1bdf5488bd5b9cef5d2aba6a1c2d..4ac8bc8dc326ef12c4ffdfdf8325f3111ca5b665 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -317,7 +317,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -44,7 +44,7 @@ index a23dc2f8f4475de1ee35bf18a7a8a53233ccac12..226af44fd469053451a0403a95ffb446
this.used.set(start, start + size);
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
index ba1b6760430babcea9338f4243abbaeb27883df7..b256e0d0cfed34f736f6f1f1128c8cbc6ef1f55b 100644
index ff092c6d0cd436f14a9a4ff5c8ddbb5538d1a8c5..16f07007a0f73ec0c6f421c9b082518e87e8cc7b 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@@ -51,6 +51,354 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche

View file

@ -279,7 +279,7 @@ index 6b8ed8a0baaf4a57d20e57cec3400af5561ddd79..48604e7f96adc9e226e034054c5e2bad
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index b29dbab3c26c078eb993183d808149d958857f3a..38b5eef0b5ff38f9a8dfa59822d7b41336108f49 100644
index 4ac8bc8dc326ef12c4ffdfdf8325f3111ca5b665..ca70815b73199835b88c9d68c8a01699536d320f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -764,6 +764,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -6,7 +6,7 @@ Subject: [PATCH] Incremental chunk and player saving
Feature patch
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 38b5eef0b5ff38f9a8dfa59822d7b41336108f49..b33b68649e67de08719b30e98650c84f4c3c18d6 100644
index ca70815b73199835b88c9d68c8a01699536d320f..be6e64d5c858961b19eb7b1b028530c1eb4c68d7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1007,7 +1007,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -10,7 +10,7 @@ Areas affected by lag comepnsation:
Feature patch
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index b33b68649e67de08719b30e98650c84f4c3c18d6..e636a96ea6220fda671a31d3d9cdea468a558768 100644
index be6e64d5c858961b19eb7b1b028530c1eb4c68d7..11a0bf52d891d79e3520de91d270b876871510f7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -331,6 +331,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -11,7 +11,7 @@ sleep by default, which avoids the problem and makes it more obvious to check if
enabled. We also unload chunks during sleep to prevent memory leaks caused by plugin chunk loads.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index e636a96ea6220fda671a31d3d9cdea468a558768..64b56abf8900d0424100da460fc68ac964394793 100644
index 11a0bf52d891d79e3520de91d270b876871510f7..317bb0bd16d8125a40c37b75be1d4d0461bcf9ce 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1638,6 +1638,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -5,7 +5,7 @@ Subject: [PATCH] API to check if the server is sleeping
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 64b56abf8900d0424100da460fc68ac964394793..5d070f036dae6d93f863c55192b557419634456d 100644
index 317bb0bd16d8125a40c37b75be1d4d0461bcf9ce..135fb7f722947a57169f0ce584cb031f4c54c854 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -3186,4 +3186,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa

View file

@ -5,7 +5,7 @@ Subject: [PATCH] API to allow/disallow tick sleeping
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 5d070f036dae6d93f863c55192b557419634456d..c26e3a239441376f2694782d4f07943538677c71 100644
index 135fb7f722947a57169f0ce584cb031f4c54c854..780582ebaa8deb0c0b0c8de17de5abcebafa4bd3 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -332,6 +332,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa