From c7b3e4ea96eeef1d8beeb9fb4da7e70f70324f77 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Mon, 1 Apr 2024 01:28:14 -0400 Subject: [PATCH] Add ability to use Virtual Thread for Linear region flusher --- ...inearPurpur-Add-Linear-region-format.patch | 48 +++++++--- ...-Virtual-Thread-for-async-scheduler.patch} | 11 ++- ...76-Virtual-Thread-for-linear-flusher.patch | 93 +++++++++++++++++++ ...a-shadow-fork-that-supports-Java-21.patch} | 0 ...l.patch => 0078-Chat-Image-protocol.patch} | 0 ...l.patch => 0079-Asteor-Bar-protocol.patch} | 0 ...onfigurable-chat-message-signatures.patch} | 0 ...081-Block-log4j-rce-exploit-in-chat.patch} | 0 ... => 0082-Cache-player-profileResult.patch} | 0 ...n-editable-sign-warning-spam-in-con.patch} | 0 ...ed.patch => 0084-Matter-Secure-Seed.patch} | 0 ...d.patch => 0085-Matter-Seed-Command.patch} | 0 12 files changed, 134 insertions(+), 18 deletions(-) rename patches/server/{0075-Ability-to-use-Virtual-Thread-for-async-scheduler.patch => 0075-Virtual-Thread-for-async-scheduler.patch} (91%) create mode 100644 patches/server/0076-Virtual-Thread-for-linear-flusher.patch rename patches/server/{0076-Use-a-shadow-fork-that-supports-Java-21.patch => 0077-Use-a-shadow-fork-that-supports-Java-21.patch} (100%) rename patches/server/{0077-Chat-Image-protocol.patch => 0078-Chat-Image-protocol.patch} (100%) rename patches/server/{0078-Asteor-Bar-protocol.patch => 0079-Asteor-Bar-protocol.patch} (100%) rename patches/server/{0079-Mirai-Configurable-chat-message-signatures.patch => 0080-Mirai-Configurable-chat-message-signatures.patch} (100%) rename patches/server/{0080-Block-log4j-rce-exploit-in-chat.patch => 0081-Block-log4j-rce-exploit-in-chat.patch} (100%) rename patches/server/{0081-Cache-player-profileResult.patch => 0082-Cache-player-profileResult.patch} (100%) rename patches/server/{0082-Prevent-change-non-editable-sign-warning-spam-in-con.patch => 0083-Prevent-change-non-editable-sign-warning-spam-in-con.patch} (100%) rename patches/server/{0083-Matter-Secure-Seed.patch => 0084-Matter-Secure-Seed.patch} (100%) rename patches/server/{0084-Matter-Seed-Command.patch => 0085-Matter-Seed-Command.patch} (100%) diff --git a/patches/server/0054-LinearPurpur-Add-Linear-region-format.patch b/patches/server/0054-LinearPurpur-Add-Linear-region-format.patch index 9b750acb..1a86bbcb 100644 --- a/patches/server/0054-LinearPurpur-Add-Linear-region-format.patch +++ b/patches/server/0054-LinearPurpur-Add-Linear-region-format.patch @@ -704,10 +704,10 @@ index f6338904ca0961cfd67326908e9cf72e37c6e86e..21c15670c0c9b988472ac8e875a1c033 public boolean alwaysTameInCreative = false; diff --git a/src/main/java/org/purpurmc/purpur/region/AbstractRegionFile.java b/src/main/java/org/purpurmc/purpur/region/AbstractRegionFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..e6ab1ca9a699c3f57855f2acc8d08b8a005bce2f +index 0000000000000000000000000000000000000000..4f903d384959e4353ac1b310b9a70beeb2ce7f6a --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/region/AbstractRegionFile.java -@@ -0,0 +1,31 @@ +@@ -0,0 +1,43 @@ +package org.purpurmc.purpur.region; + +import net.minecraft.nbt.CompoundTag; @@ -722,21 +722,33 @@ index 0000000000000000000000000000000000000000..e6ab1ca9a699c3f57855f2acc8d08b8a + +public interface AbstractRegionFile { + void flush() throws IOException; ++ + void clear(ChunkPos pos) throws IOException; ++ + void close() throws IOException; ++ + void setStatus(int x, int z, ChunkStatus status); ++ + void setOversized(int x, int z, boolean b) throws IOException; + + boolean hasChunk(ChunkPos pos); ++ + boolean doesChunkExist(ChunkPos pos) throws Exception; ++ + boolean isOversized(int x, int z); ++ + boolean recalculateHeader() throws IOException; + + DataOutputStream getChunkDataOutputStream(ChunkPos pos) throws IOException; ++ + DataInputStream getChunkDataInputStream(ChunkPos pos) throws IOException; ++ + CompoundTag getOversizedData(int x, int z) throws IOException; ++ + ChunkStatus getStatusIfCached(int x, int z); ++ + ReentrantLock getFileLock(); ++ + Path getRegionFile(); +} diff --git a/src/main/java/org/purpurmc/purpur/region/AbstractRegionFileFactory.java b/src/main/java/org/purpurmc/purpur/region/AbstractRegionFileFactory.java @@ -776,10 +788,10 @@ index 0000000000000000000000000000000000000000..c88ff6fda185a8489cbefa51a7b09ccb +} diff --git a/src/main/java/org/purpurmc/purpur/region/LinearRegionFile.java b/src/main/java/org/purpurmc/purpur/region/LinearRegionFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..731a90436cae2e615c228c07f042fa112b95a8d2 +index 0000000000000000000000000000000000000000..041f97f32beabc52400f57d056de3d4d313d3e74 --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/region/LinearRegionFile.java -@@ -0,0 +1,316 @@ +@@ -0,0 +1,317 @@ +package org.purpurmc.purpur.region; + +import com.github.luben.zstd.ZstdInputStream; @@ -1044,7 +1056,7 @@ index 0000000000000000000000000000000000000000..731a90436cae2e615c228c07f042fa11 + + @Nullable + public synchronized DataInputStream getChunkDataInputStream(ChunkPos pos) { -+ if(this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) { ++ if (this.bufferUncompressedSize[getChunkIndex(pos.x, pos.z)] != 0) { + byte[] content = new byte[bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]]; + this.decompressor.decompress(this.buffer[getChunkIndex(pos.x, pos.z)], 0, content, 0, bufferUncompressedSize[getChunkIndex(pos.x, pos.z)]); + return new DataInputStream(new ByteArrayInputStream(content)); @@ -1086,7 +1098,8 @@ index 0000000000000000000000000000000000000000..731a90436cae2e615c228c07f042fa11 + return false; + } + -+ public void setOversized(int x, int z, boolean something) {} ++ public void setOversized(int x, int z, boolean something) { ++ } + + public CompoundTag getOversizedData(int x, int z) throws IOException { + throw new IOException("getOversizedData is a stub " + this.path); @@ -1098,30 +1111,35 @@ index 0000000000000000000000000000000000000000..731a90436cae2e615c228c07f042fa11 +} diff --git a/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java b/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java new file mode 100644 -index 0000000000000000000000000000000000000000..60f8ed586676609b9be7626eebf865aaaee92ac2 +index 0000000000000000000000000000000000000000..0d3d9193e8d8f72141dc155840c5eed1a744761c --- /dev/null +++ b/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java -@@ -0,0 +1,45 @@ +@@ -0,0 +1,50 @@ +package org.purpurmc.purpur.region; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; ++ +import java.util.Queue; +import java.util.concurrent.*; ++ ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; +import org.purpurmc.purpur.PurpurConfig; +import org.bukkit.Bukkit; + +public class LinearRegionFileFlusher { ++ private final Logger LOGGER = LogManager.getLogger(getClass().getName()); + private final Queue savingQueue = new LinkedBlockingQueue<>(); + private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor( -+ new ThreadFactoryBuilder() -+ .setNameFormat("linear-flush-scheduler") -+ .build() ++ new ThreadFactoryBuilder() ++ .setNameFormat("linear-flush-scheduler") ++ .build() + ); + private final ExecutorService executor = Executors.newFixedThreadPool( -+ PurpurConfig.linearFlushThreads, -+ new ThreadFactoryBuilder() -+ .setNameFormat("linear-flusher-%d") -+ .build() ++ PurpurConfig.linearFlushThreads, ++ new ThreadFactoryBuilder() ++ .setNameFormat("linear-flusher-%d") ++ .build() + ); + + public LinearRegionFileFlusher() { diff --git a/patches/server/0075-Ability-to-use-Virtual-Thread-for-async-scheduler.patch b/patches/server/0075-Virtual-Thread-for-async-scheduler.patch similarity index 91% rename from patches/server/0075-Ability-to-use-Virtual-Thread-for-async-scheduler.patch rename to patches/server/0075-Virtual-Thread-for-async-scheduler.patch index 9dcfd2c6..63360d6a 100644 --- a/patches/server/0075-Ability-to-use-Virtual-Thread-for-async-scheduler.patch +++ b/patches/server/0075-Virtual-Thread-for-async-scheduler.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: nostalfinals Date: Tue, 12 Mar 2024 00:36:29 +0800 -Subject: [PATCH] Ability to use Virtual Thread for async scheduler +Subject: [PATCH] Virtual Thread for async scheduler diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -17,13 +17,15 @@ index ee166ad76bd2c143e04e4bf6bd9991bc90ab99a5..13f3f8628143ffc22a2d2c2129ea4836 tryPreloadClass("org.slf4j.helpers.FormattingTuple"); tryPreloadClass("org.slf4j.helpers.BasicMarker"); diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..3f119f51e1af89f63be00f5a54a9814358f04be6 100644 +index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..ba7784780a578350992be3e2cfcb9791aa805838 100644 --- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java -@@ -25,30 +25,50 @@ package org.bukkit.craftbukkit.scheduler; +@@ -25,30 +25,55 @@ package org.bukkit.craftbukkit.scheduler; import com.destroystokyo.paper.ServerSchedulerReportingWrapper; import com.google.common.util.concurrent.ThreadFactoryBuilder; ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; +import org.galemc.gale.virtualthread.VirtualThreadService; import org.bukkit.plugin.Plugin; @@ -43,6 +45,7 @@ index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..3f119f51e1af89f63be00f5a54a98143 - private final ThreadPoolExecutor executor = new ThreadPoolExecutor( - 4, Integer.MAX_VALUE,30L, TimeUnit.SECONDS, new SynchronousQueue<>(), - new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build()); // Paper ++ private final Logger LOGGER = LogManager.getLogger(getClass().getName()); // Leaf - Class logger + private Executor executor; // Leaf - use super class private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() .setNameFormat("Craft Async Scheduler Management Thread").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build()); // Paper @@ -57,10 +60,12 @@ index 9c1aff17aabd062640e3f451a2ef8c50a7c62f10..3f119f51e1af89f63be00f5a54a98143 + if (VirtualThreadService.getJavaMajorVersion() >= VirtualThreadService.minimumJavaMajorVersionWithoutFeaturePreview && org.dreeam.leaf.config.modules.opt.VT4BukkitScheduler.enabled) { + try { + Method newThreadPerTaskExecutor = Executors.class.getMethod("newThreadPerTaskExecutor", ThreadFactory.class); ++ + executor = (Executor) newThreadPerTaskExecutor.invoke(null, VirtualThreadService.get().createFactory()); + //executor = Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name("Craft Scheduler Thread - ", 0).factory()); // Leaf - When Minecraft using Java21 + return; + } catch (Exception ignored) { ++ LOGGER.error("Failed to create Virtual Thread executor! Fallback to default executor."); + } + } + diff --git a/patches/server/0076-Virtual-Thread-for-linear-flusher.patch b/patches/server/0076-Virtual-Thread-for-linear-flusher.patch new file mode 100644 index 00000000..dfd6eba5 --- /dev/null +++ b/patches/server/0076-Virtual-Thread-for-linear-flusher.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Radiation_pi +Date: Mon, 25 Mar 2024 23:00:19 +0800 +Subject: [PATCH] Virtual Thread for linear flusher + + +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/VT4LinearFlusher.java b/src/main/java/org/dreeam/leaf/config/modules/opt/VT4LinearFlusher.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d4576c9930d12548d4302207f61a0eb8b1fa7b7a +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/VT4LinearFlusher.java +@@ -0,0 +1,29 @@ ++package org.dreeam.leaf.config.modules.opt; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class VT4LinearFlusher implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "use_virtual_thread_for_linear_flusher"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = false; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("performance.use_virtual_thread_for_linear_flusher", """ ++ Use the new Virtual Thread introduced in JDK 21 for Linear Region Flusher. ++ """); ++ } ++} +diff --git a/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java b/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java +index 0d3d9193e8d8f72141dc155840c5eed1a744761c..339157b5e5a81e3c1c5b54fbd9e3c53ea3f51716 100644 +--- a/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java ++++ b/src/main/java/org/purpurmc/purpur/region/LinearRegionFileFlusher.java +@@ -4,9 +4,12 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; + + import java.util.Queue; + import java.util.concurrent.*; ++import java.lang.reflect.InvocationTargetException; ++import java.lang.reflect.Method; + + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import org.galemc.gale.virtualthread.VirtualThreadService; + import org.purpurmc.purpur.PurpurConfig; + import org.bukkit.Bukkit; + +@@ -18,12 +21,28 @@ public class LinearRegionFileFlusher { + .setNameFormat("linear-flush-scheduler") + .build() + ); +- private final ExecutorService executor = Executors.newFixedThreadPool( +- PurpurConfig.linearFlushThreads, +- new ThreadFactoryBuilder() +- .setNameFormat("linear-flusher-%d") +- .build() +- ); ++ ++ private ExecutorService executor; ++ ++ { ++ try { ++ if (VirtualThreadService.getJavaMajorVersion() >= VirtualThreadService.minimumJavaMajorVersionWithoutFeaturePreview && org.dreeam.leaf.config.modules.opt.VT4LinearFlusher.enabled) { ++ Method newThreadPerTaskExecutor = Executors.class.getMethod("newThreadPerTaskExecutor", ThreadFactory.class); ++ ++ executor = (ExecutorService) newThreadPerTaskExecutor.invoke(null, VirtualThreadService.get().createFactory()); ++ } else { ++ throw new UnsupportedOperationException(); ++ } ++ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | ++ UnsupportedOperationException e) { ++ LOGGER.error("Failed to create Virtual Thread executor! Fallback to default executor."); ++ executor = Executors.newFixedThreadPool( ++ PurpurConfig.linearFlushThreads, ++ new ThreadFactoryBuilder() ++ .setNameFormat("linear-flusher-%d") ++ .build()); ++ } ++ } + + public LinearRegionFileFlusher() { + Bukkit.getLogger().info("Using " + PurpurConfig.linearFlushThreads + " threads for linear region flushing."); diff --git a/patches/server/0076-Use-a-shadow-fork-that-supports-Java-21.patch b/patches/server/0077-Use-a-shadow-fork-that-supports-Java-21.patch similarity index 100% rename from patches/server/0076-Use-a-shadow-fork-that-supports-Java-21.patch rename to patches/server/0077-Use-a-shadow-fork-that-supports-Java-21.patch diff --git a/patches/server/0077-Chat-Image-protocol.patch b/patches/server/0078-Chat-Image-protocol.patch similarity index 100% rename from patches/server/0077-Chat-Image-protocol.patch rename to patches/server/0078-Chat-Image-protocol.patch diff --git a/patches/server/0078-Asteor-Bar-protocol.patch b/patches/server/0079-Asteor-Bar-protocol.patch similarity index 100% rename from patches/server/0078-Asteor-Bar-protocol.patch rename to patches/server/0079-Asteor-Bar-protocol.patch diff --git a/patches/server/0079-Mirai-Configurable-chat-message-signatures.patch b/patches/server/0080-Mirai-Configurable-chat-message-signatures.patch similarity index 100% rename from patches/server/0079-Mirai-Configurable-chat-message-signatures.patch rename to patches/server/0080-Mirai-Configurable-chat-message-signatures.patch diff --git a/patches/server/0080-Block-log4j-rce-exploit-in-chat.patch b/patches/server/0081-Block-log4j-rce-exploit-in-chat.patch similarity index 100% rename from patches/server/0080-Block-log4j-rce-exploit-in-chat.patch rename to patches/server/0081-Block-log4j-rce-exploit-in-chat.patch diff --git a/patches/server/0081-Cache-player-profileResult.patch b/patches/server/0082-Cache-player-profileResult.patch similarity index 100% rename from patches/server/0081-Cache-player-profileResult.patch rename to patches/server/0082-Cache-player-profileResult.patch diff --git a/patches/server/0082-Prevent-change-non-editable-sign-warning-spam-in-con.patch b/patches/server/0083-Prevent-change-non-editable-sign-warning-spam-in-con.patch similarity index 100% rename from patches/server/0082-Prevent-change-non-editable-sign-warning-spam-in-con.patch rename to patches/server/0083-Prevent-change-non-editable-sign-warning-spam-in-con.patch diff --git a/patches/server/0083-Matter-Secure-Seed.patch b/patches/server/0084-Matter-Secure-Seed.patch similarity index 100% rename from patches/server/0083-Matter-Secure-Seed.patch rename to patches/server/0084-Matter-Secure-Seed.patch diff --git a/patches/server/0084-Matter-Seed-Command.patch b/patches/server/0085-Matter-Seed-Command.patch similarity index 100% rename from patches/server/0084-Matter-Seed-Command.patch rename to patches/server/0085-Matter-Seed-Command.patch