From 20fc654252ca61bc9977f59f186a34135a1b2b96 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Tue, 27 Feb 2024 23:04:22 -0500 Subject: [PATCH] Refactor LeafConfig & Format patches Co-Authored-By: M2ke4U <79621885+MrHua269@users.noreply.github.com> --- patches/server/0002-Leaf-Config.patch | 432 +++++++++++------- patches/server/0003-Pufferfish-Utils.patch | 225 ++++----- patches/server/0004-Pufferfish-Sentry.patch | 347 +++++++------- ...005-Pufferfish-Optimize-mob-spawning.patch | 74 +-- ...fferfish-Dynamic-Activation-of-Brain.patch | 138 +++--- ...tle-goal-selector-during-inactive-ti.patch | 62 ++- .../server/0008-Pufferfish-Entity-TTL.patch | 76 +-- .../server/0009-Purpur-Server-Changes.patch | 30 +- ...-Purpur-Configurable-server-mod-name.patch | 43 +- .../0011-Configurable-server-GUI-name.patch | 49 ++ .../0011-Configurable-server-Gui-name.patch | 43 -- patches/server/0013-Bump-Dependencies.patch | 18 +- ... 0014-Remove-vanilla-username-check.patch} | 59 ++- ...eck-for-Broken-BungeeCord-Configurat.patch | 58 ++- ...Remove-UseItemOnPacket-Too-Far-Check.patch | 56 ++- ...on-for-spigot-item-merging-mechanism.patch | 51 ++- ...ion-optimized-PoweredRailBlock-logic.patch | 57 ++- .../server/0029-Leaves-Jade-Protocol.patch | 49 +- .../0030-Leaves-Appleskin-Protocol.patch | 33 +- .../0031-Leaves-Xaero-Map-Protocol.patch | 45 +- .../0032-Leaves-Syncmatica-Protocol.patch | 45 +- ...aves-Disable-moved-wrongly-threshold.patch | 79 ++-- ...-Fix-vehicle-teleport-by-end-gateway.patch | 47 +- .../server/0038-Petal-Async-Pathfinding.patch | 145 +++--- .../0039-Petal-Multithreaded-Tracker.patch | 101 ++-- ...e-minecart-vehicle-collision-results.patch | 65 +-- ...ndom-for-xaeroMapServerID-generation.patch | 30 +- ...oleAppender-NPE-error-on-server-clos.patch | 8 +- ...inearPurpur-Add-Linear-region-format.patch | 14 +- ...p-MapItem-update-if-the-map-does-not.patch | 51 ++- ...gg-and-snowball-can-knockback-player.patch | 50 +- ...-s-method-to-fix-plugin-incompatibil.patch | 6 +- .../0064-Configurable-fix-tripwire-dupe.patch | 43 +- .../server/0067-Including-5s-in-getTPS.patch | 48 +- 34 files changed, 1531 insertions(+), 1146 deletions(-) create mode 100644 patches/server/0011-Configurable-server-GUI-name.patch delete mode 100644 patches/server/0011-Configurable-server-Gui-name.patch rename patches/server/{0014-Remove-Mojang-username-check.patch => 0014-Remove-vanilla-username-check.patch} (55%) diff --git a/patches/server/0002-Leaf-Config.patch b/patches/server/0002-Leaf-Config.patch index 704b6b27..45e8eb34 100644 --- a/patches/server/0002-Leaf-Config.patch +++ b/patches/server/0002-Leaf-Config.patch @@ -5,209 +5,313 @@ Subject: [PATCH] Leaf Config diff --git a/build.gradle.kts b/build.gradle.kts -index a8a720045804cded8f8dffc1bfdd20710b8f0c82..c8ba9702926c55f783d35a7df9b3cfc3af27f005 100644 +index a8a720045804cded8f8dffc1bfdd20710b8f0c82..a53b30ab2315fc0b2ce07d9449042842e6ca3b39 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -56,6 +56,13 @@ dependencies { - runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") - runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") - -+ // Leaf start -+ implementation("org.yaml:snakeyaml:2.2") -+ implementation("com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4") { -+ exclude(group = "org.yaml", module = "snakeyaml") -+ } -+ // Leaf end +@@ -21,6 +21,9 @@ dependencies { + exclude("io.papermc.paper", "paper-api") + } + // Gale end - project setup + - testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test - testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") - testImplementation("org.hamcrest:hamcrest:2.2") ++ implementation("com.electronwill.night-config:toml:3.6.7") // Leaf - Night config ++ + // Paper start + implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("net.minecrell:terminalconsoleappender:1.3.0") diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 2c8eb9294890955f71382ed3884874cc827bab5e..ee29ceff6804383edc229cd302ab07345f96658b 100644 +index 2c8eb9294890955f71382ed3884874cc827bab5e..bebafdf670ef1783ccae3b93fcda7d0eaef38d3e 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -232,6 +232,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - SIMDDetection.initialize(); - } catch (Throwable ignored) {} - // Gale start - Pufferfish - SIMD support -+ org.dreeam.leaf.LeafConfig.load(); // Leaf - - this.setPvpAllowed(dedicatedserverproperties.pvp); - this.setFlightAllowed(dedicatedserverproperties.allowFlight); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java +@@ -212,6 +212,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface + galeConfigurations.initializeGlobalConfiguration(this.registryAccess()); + galeConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess()); + // Gale end - Gale configuration ++ org.dreeam.leaf.config.LeafConfig.loadConfig(); // Leaf + // Paper start - fix converting txt to json file; convert old users earlier after PlayerList creation but before file load/save + if (this.convertOldUsers()) { + this.getProfileCache().save(false); // Paper +diff --git a/src/main/java/org/dreeam/leaf/config/ConfigInfo.java b/src/main/java/org/dreeam/leaf/config/ConfigInfo.java new file mode 100644 -index 0000000000000000000000000000000000000000..74becc68c443917b0ec75bfe40ca4079532e0ac0 +index 0000000000000000000000000000000000000000..60b81df55d33a9546ac77bf3b8ef667cb03094db --- /dev/null -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -0,0 +1,171 @@ -+package org.dreeam.leaf; ++++ b/src/main/java/org/dreeam/leaf/config/ConfigInfo.java +@@ -0,0 +1,10 @@ ++package org.dreeam.leaf.config; + -+import com.google.common.collect.ImmutableMap; -+import net.minecraft.server.MinecraftServer; -+import org.bukkit.configuration.ConfigurationSection; -+import org.bukkit.configuration.MemoryConfiguration; -+import org.jetbrains.annotations.Nullable; -+import org.simpleyaml.configuration.comments.CommentType; -+import org.simpleyaml.configuration.file.YamlFile; -+import org.simpleyaml.exceptions.InvalidConfigurationException; ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++ ++@Retention(RetentionPolicy.RUNTIME) ++public @interface ConfigInfo { ++ String baseName(); ++ String comments() default ""; ++} +diff --git a/src/main/java/org/dreeam/leaf/config/DoNotLoad.java b/src/main/java/org/dreeam/leaf/config/DoNotLoad.java +new file mode 100644 +index 0000000000000000000000000000000000000000..42ce82d388336906a91547b81f6f70766f2b10f0 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/DoNotLoad.java +@@ -0,0 +1,8 @@ ++package org.dreeam.leaf.config; ++ ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++ ++@Retention(RetentionPolicy.RUNTIME) ++public @interface DoNotLoad { ++} +diff --git a/src/main/java/org/dreeam/leaf/config/EnumConfigCategory.java b/src/main/java/org/dreeam/leaf/config/EnumConfigCategory.java +new file mode 100644 +index 0000000000000000000000000000000000000000..273bdcaafb3953e2a9830851d9ec7ec4a79f9d17 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/EnumConfigCategory.java +@@ -0,0 +1,22 @@ ++package org.dreeam.leaf.config; ++ ++public enum EnumConfigCategory { ++ ++ ASYNC("async"), ++ PERFORMANCE("performance"), ++ NETWORK("network"), ++ FIXES("fixes"), ++ MISC("misc"), ++ GAMEPLAY("gameplay"), ++ WIP("wip"); ++ ++ private final String baseKeyName; ++ ++ EnumConfigCategory(String baseKeyName) { ++ this.baseKeyName = baseKeyName; ++ } ++ ++ public String getBaseKeyName() { ++ return this.baseKeyName; ++ } ++} +diff --git a/src/main/java/org/dreeam/leaf/config/IConfigModule.java b/src/main/java/org/dreeam/leaf/config/IConfigModule.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2e23a83de1d2f3bbbd7014b265ed7a195e83e799 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/IConfigModule.java +@@ -0,0 +1,22 @@ ++package org.dreeam.leaf.config; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import org.jetbrains.annotations.NotNull; ++ ++public interface IConfigModule { ++ ++ EnumConfigCategory getCategory(); ++ String getBaseName(); ++ ++ default void onLoaded(CommentedFileConfig configInstance) { ++ } ++ ++ default T get(String keyName, T defaultValue, @NotNull CommentedFileConfig config) { ++ if (!config.contains(keyName)) { ++ config.set(keyName, defaultValue); ++ return defaultValue; ++ } ++ ++ return config.get(keyName); ++ } ++} +diff --git a/src/main/java/org/dreeam/leaf/config/LeafConfig.java b/src/main/java/org/dreeam/leaf/config/LeafConfig.java +new file mode 100644 +index 0000000000000000000000000000000000000000..86cb8a187d751c2e2842a0998ac07bcff15ca3cf +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/LeafConfig.java +@@ -0,0 +1,193 @@ ++package org.dreeam.leaf.config; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; -+import java.lang.reflect.Method; ++import java.lang.reflect.Field; ++import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; -+import java.util.List; -+import java.util.Map; ++import java.net.JarURLConnection; ++import java.net.URL; ++import java.net.URLDecoder; ++import java.nio.charset.StandardCharsets; ++import java.util.*; ++import java.util.jar.JarEntry; ++import java.util.jar.JarFile; ++ ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; + +public class LeafConfig { ++ public static final Logger logger = LogManager.getLogger("LeafConfig"); ++ private static final File baseConfigFolder = new File("leaf_config"); ++ private static final File baseConfigFile = new File(baseConfigFolder, "leaf_global_config.toml"); ++ private static final Set allInstanced = new HashSet<>(); ++ private static CommentedFileConfig configFileInstance; + -+ private static final YamlFile config = new YamlFile(); -+ private static int updates = 0; ++ public static void loadConfig() throws IOException { ++ baseConfigFolder.mkdirs(); + -+ private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) { -+ ConfigurationSection newSection = new MemoryConfiguration(); -+ for (String key : section.getKeys(false)) { -+ if (section.isConfigurationSection(key)) { -+ newSection.set(key, convertToBukkit(section.getConfigurationSection(key))); -+ } else { -+ newSection.set(key, section.get(key)); ++ if (!baseConfigFile.exists()) { ++ baseConfigFile.createNewFile(); ++ } ++ ++ configFileInstance = CommentedFileConfig.ofConcurrent(baseConfigFile); ++ ++ configFileInstance.load(); ++ configFileInstance.getComment(""" ++ Leaf Config ++ Github Repo: https://github.com/Winds-Studio/Leaf ++ Discord: dreeam___ | QQ: 2682173972"""); ++ ++ try { ++ instanceAllModule(); ++ loadAllModules(); ++ } catch (Exception e) { ++ logger.error("Failed to load config modules!", e); ++ } ++ ++ configFileInstance.save(); ++ } ++ ++ private static void loadAllModules() throws IllegalAccessException { ++ for (IConfigModule instanced : allInstanced) { ++ loadForSingle(instanced); ++ } ++ } ++ ++ private static void instanceAllModule() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { ++ for (Class clazz : getClasses("org.dreeam.leaf.config.modules")) { ++ if (IConfigModule.class.isAssignableFrom(clazz)) { ++ allInstanced.add((IConfigModule) clazz.getConstructor().newInstance()); + } + } -+ return newSection; + } + -+ public static ConfigurationSection getConfigCopy() { -+ return convertToBukkit(config); -+ } ++ private static void loadForSingle(@NotNull IConfigModule singleConfigModule) throws IllegalAccessException { ++ final EnumConfigCategory category = singleConfigModule.getCategory(); + -+ public static int getUpdates() { -+ return updates; -+ } ++ Field[] fields = singleConfigModule.getClass().getDeclaredFields(); + -+ public static void load() throws IOException { -+ File configFile = new File("leaf.yml"); ++ for (Field field : fields) { ++ int modifiers = field.getModifiers(); ++ if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) { ++ boolean skipLoad = field.getAnnotation(DoNotLoad.class) != null; ++ ConfigInfo configInfo = field.getAnnotation(ConfigInfo.class); + -+ if (configFile.exists()) { -+ try { -+ config.load(configFile); -+ } catch (InvalidConfigurationException e) { -+ throw new IOException(e); ++ if (skipLoad || configInfo == null) { ++ continue; ++ } ++ ++ final String fullConfigKeyName = category.getBaseKeyName() + "." + singleConfigModule.getBaseName() + "." + configInfo.baseName(); ++ ++ field.setAccessible(true); ++ final Object currentValue = field.get(null); ++ ++ if (!configFileInstance.contains(fullConfigKeyName)) { ++ if (currentValue == null) { ++ throw new UnsupportedOperationException("Config " + singleConfigModule.getBaseName() + "tried to add an null default value!"); ++ } ++ ++ final String comments = configInfo.comments(); ++ ++ if (!comments.isBlank()) { ++ configFileInstance.setComment(fullConfigKeyName, comments); ++ } ++ ++ configFileInstance.add(fullConfigKeyName, currentValue); ++ continue; ++ } ++ ++ final Object actuallyValue = configFileInstance.get(fullConfigKeyName); ++ field.set(null, actuallyValue); + } + } + -+ getString("info.version", "1.2"); -+ setComment("info", -+ "Leaf Config", -+ "Github Repo: https://github.com/Winds-Studio/Leaf", -+ "Discord: dreeam___ | QQ: 2682173972"); ++ singleConfigModule.onLoaded(configFileInstance); ++ } + -+ for (Method method : LeafConfig.class.getDeclaredMethods()) { -+ if (Modifier.isStatic(method.getModifiers()) && Modifier.isPrivate(method.getModifiers()) && method.getParameterCount() == 0 && -+ method.getReturnType() == Void.TYPE && !method.getName().startsWith("lambda")) { -+ method.setAccessible(true); -+ try { -+ method.invoke(null); -+ } catch (Throwable t) { -+ MinecraftServer.LOGGER.warn("Failed to load configuration option from {}", method.getName(), t); ++ public static @NotNull Set> getClasses(String pack) { ++ Set> classes = new LinkedHashSet<>(); ++ String packageDirName = pack.replace('.', '/'); ++ Enumeration dirs; ++ ++ try { ++ dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName); ++ while (dirs.hasMoreElements()) { ++ URL url = dirs.nextElement(); ++ String protocol = url.getProtocol(); ++ if ("file".equals(protocol)) { ++ String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8); ++ findClassesInPackageByFile(pack, filePath, classes); ++ } else if ("jar".equals(protocol)) { ++ JarFile jar; ++ try { ++ jar = ((JarURLConnection) url.openConnection()).getJarFile(); ++ Enumeration entries = jar.entries(); ++ findClassesInPackageByJar(pack, entries, packageDirName, classes); ++ } catch (IOException e) { ++ throw new RuntimeException(e); ++ } ++ } ++ } ++ } catch (IOException e) { ++ throw new RuntimeException(e); ++ } ++ ++ return classes; ++ } ++ ++ private static void findClassesInPackageByFile(String packageName, String packagePath, Set> classes) { ++ File dir = new File(packagePath); ++ ++ if (!dir.exists() || !dir.isDirectory()) { ++ return; ++ } ++ ++ File[] dirfiles = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(".class")); ++ if (dirfiles != null) { ++ for (File file : dirfiles) { ++ if (file.isDirectory()) { ++ findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), classes); ++ } else { ++ String className = file.getName().substring(0, file.getName().length() - 6); ++ try { ++ classes.add(Class.forName(packageName + '.' + className)); ++ } catch (ClassNotFoundException e) { ++ throw new RuntimeException(e); ++ } + } + } + } -+ -+ updates++; -+ -+ config.save(configFile); -+ + } + -+ private static void setComment(String key, String... comment) { -+ if (config.contains(key)) { -+ config.setComment(key, String.join("\n", comment), CommentType.BLOCK); -+ } -+ } ++ private static void findClassesInPackageByJar(String packageName, Enumeration entries, String packageDirName, Set> classes) { ++ while (entries.hasMoreElements()) { ++ JarEntry entry = entries.nextElement(); ++ String name = entry.getName(); + -+ private static void ensureDefault(String key, Object defaultValue, String... comment) { -+ if (!config.contains(key)) { -+ config.set(key, defaultValue); -+ config.setComment(key, String.join("\n", comment), CommentType.BLOCK); -+ } -+ } ++ if (name.charAt(0) == '/') { ++ name = name.substring(1); ++ } + -+ private static void set(String key, Object defaultValue) { -+ config.addDefault(key, defaultValue); -+ config.set(key, defaultValue); -+ } ++ if (name.startsWith(packageDirName)) { ++ int idx = name.lastIndexOf('/'); + -+ private static boolean getBoolean(String key, boolean defaultValue, String... comment) { -+ return getBoolean(key, null, defaultValue, comment); -+ } ++ if (idx != -1) { ++ packageName = name.substring(0, idx).replace('/', '.'); ++ } + -+ private static boolean getBoolean(String key, @Nullable String oldKey, boolean defaultValue, String... comment) { -+ ensureDefault(key, defaultValue, comment); -+ return config.getBoolean(key, defaultValue); -+ } -+ -+ private static int getInt(String key, int defaultValue, String... comment) { -+ return getInt(key, null, defaultValue, comment); -+ } -+ -+ private static int getInt(String key, @Nullable String oldKey, int defaultValue, String... comment) { -+ ensureDefault(key, defaultValue, comment); -+ return config.getInt(key, defaultValue); -+ } -+ -+ private static double getDouble(String key, double defaultValue, String... comment) { -+ return getDouble(key, null, defaultValue, comment); -+ } -+ -+ private static double getDouble(String key, @Nullable String oldKey, double defaultValue, String... comment) { -+ ensureDefault(key, defaultValue, comment); -+ return config.getDouble(key, defaultValue); -+ } -+ -+ private static String getString(String key, String defaultValue, String... comment) { -+ return getOldString(key, null, defaultValue, comment); -+ } -+ -+ private static String getOldString(String key, @Nullable String oldKey, String defaultValue, String... comment) { -+ ensureDefault(key, defaultValue, comment); -+ return config.getString(key, defaultValue); -+ } -+ -+ private static List getStringList(String key, List defaultValue, String... comment) { -+ return getStringList(key, null, defaultValue, comment); -+ } -+ -+ private static List getStringList(String key, @Nullable String oldKey, List defaultValue, String... comment) { -+ ensureDefault(key, defaultValue, comment); -+ return config.getStringList(key); -+ } -+ -+ static Map getMap(String key, Map defaultValue) { -+ if (defaultValue != null && getConfigCopy().getConfigurationSection(key) == null) { -+ config.addDefault(key, defaultValue); -+ return defaultValue; -+ } -+ return toMap(getConfigCopy().getConfigurationSection(key)); -+ } -+ -+ private static Map toMap(ConfigurationSection section) { -+ ImmutableMap.Builder builder = ImmutableMap.builder(); -+ if (section != null) { -+ for (String key : section.getKeys(false)) { -+ Object obj = section.get(key); -+ if (obj != null) { -+ builder.put(key, obj instanceof ConfigurationSection val ? toMap(val) : obj); ++ if (name.endsWith(".class") && !entry.isDirectory()) { ++ String className = name.substring(packageName.length() + 1, name.length() - 6); ++ try { ++ classes.add(Class.forName(packageName + '.' + className)); ++ } catch (ClassNotFoundException e) { ++ throw new RuntimeException(e); ++ } + } + } + } -+ return builder.build(); -+ } -+ -+ private static void removal() { -+ } -+ -+ private static void performance() { -+ } -+ -+ private static void network() { + } +} diff --git a/patches/server/0003-Pufferfish-Utils.patch b/patches/server/0003-Pufferfish-Utils.patch index 0fc7b32f..ee082d52 100644 --- a/patches/server/0003-Pufferfish-Utils.patch +++ b/patches/server/0003-Pufferfish-Utils.patch @@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..53f2df00c6809618a9ee3d2ea72e85e8 +} diff --git a/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java b/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java new file mode 100644 -index 0000000000000000000000000000000000000000..0fe6243ea01f39fc43c4ca8897a70feddb7fb11d +index 0000000000000000000000000000000000000000..a62d22dc4ae2cc82cf6763e8b0ce6d4611782a57 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/util/AsyncExecutor.java @@ -0,0 +1,73 @@ @@ -74,6 +74,7 @@ index 0000000000000000000000000000000000000000..0fe6243ea01f39fc43c4ca8897a70fed + +import com.google.common.collect.Queues; +import gg.pufferfish.pufferfish.PufferfishLogger; ++ +import java.util.Queue; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; @@ -82,173 +83,175 @@ index 0000000000000000000000000000000000000000..0fe6243ea01f39fc43c4ca8897a70fed + +public class AsyncExecutor implements Runnable { + -+ private final Queue jobs = Queues.newArrayDeque(); -+ private final Lock mutex = new ReentrantLock(); -+ private final Condition cond = mutex.newCondition(); -+ private final Thread thread; -+ private volatile boolean killswitch = false; ++ private final Queue jobs = Queues.newArrayDeque(); ++ private final Lock mutex = new ReentrantLock(); ++ private final Condition cond = mutex.newCondition(); ++ private final Thread thread; ++ private volatile boolean killswitch = false; + -+ public AsyncExecutor(String threadName) { -+ this.thread = new Thread(this, threadName); -+ } ++ public AsyncExecutor(String threadName) { ++ this.thread = new Thread(this, threadName); ++ } + -+ public void start() { -+ thread.start(); -+ } ++ public void start() { ++ thread.start(); ++ } + -+ public void kill() { -+ killswitch = true; -+ cond.signalAll(); -+ } ++ public void kill() { ++ killswitch = true; ++ cond.signalAll(); ++ } + -+ public void submit(Runnable runnable) { -+ mutex.lock(); -+ try { -+ jobs.offer(runnable); -+ cond.signalAll(); -+ } finally { -+ mutex.unlock(); -+ } -+ } ++ public void submit(Runnable runnable) { ++ mutex.lock(); ++ try { ++ jobs.offer(runnable); ++ cond.signalAll(); ++ } finally { ++ mutex.unlock(); ++ } ++ } + -+ @Override -+ public void run() { -+ while (!killswitch) { -+ try { -+ Runnable runnable = takeRunnable(); -+ if (runnable != null) { -+ runnable.run(); -+ } -+ } catch (InterruptedException e) { -+ Thread.currentThread().interrupt(); -+ } catch (Exception e) { -+ PufferfishLogger.LOGGER.log(Level.SEVERE, e, () -> "Failed to execute async job for thread " + thread.getName()); -+ } -+ } -+ } ++ @Override ++ public void run() { ++ while (!killswitch) { ++ try { ++ Runnable runnable = takeRunnable(); ++ if (runnable != null) { ++ runnable.run(); ++ } ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); ++ } catch (Exception e) { ++ PufferfishLogger.LOGGER.log(Level.SEVERE, e, () -> "Failed to execute async job for thread " + thread.getName()); ++ } ++ } ++ } + -+ private Runnable takeRunnable() throws InterruptedException { -+ mutex.lock(); -+ try { -+ while (jobs.isEmpty() && !killswitch) { -+ cond.await(); -+ } ++ private Runnable takeRunnable() throws InterruptedException { ++ mutex.lock(); ++ try { ++ while (jobs.isEmpty() && !killswitch) { ++ cond.await(); ++ } + -+ if (jobs.isEmpty()) return null; // We've set killswitch -+ -+ return jobs.remove(); -+ } finally { -+ mutex.unlock(); -+ } -+ } ++ if (jobs.isEmpty()) return null; // We've set killswitch + ++ return jobs.remove(); ++ } finally { ++ mutex.unlock(); ++ } ++ } +} diff --git a/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java new file mode 100644 -index 0000000000000000000000000000000000000000..a93ee99c2399def1e221260547a3e6bce2d621fa +index 0000000000000000000000000000000000000000..a9052e71b943b2bc4f07732fa1c3712518dcd3e7 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/util/AsyncPlayerAreaMap.java -@@ -0,0 +1,31 @@ +@@ -0,0 +1,32 @@ +package gg.pufferfish.pufferfish.util; + +import com.destroystokyo.paper.util.misc.PlayerAreaMap; +import com.destroystokyo.paper.util.misc.PooledLinkedHashSets; ++ +import java.util.concurrent.ConcurrentHashMap; ++ +import net.minecraft.server.level.ServerPlayer; + +public final class AsyncPlayerAreaMap extends PlayerAreaMap { + -+ public AsyncPlayerAreaMap() { -+ super(); -+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f)); -+ } ++ public AsyncPlayerAreaMap() { ++ super(); ++ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f)); ++ } + -+ public AsyncPlayerAreaMap(final PooledLinkedHashSets pooledHashSets) { -+ super(pooledHashSets); -+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f)); -+ } ++ public AsyncPlayerAreaMap(final PooledLinkedHashSets pooledHashSets) { ++ super(pooledHashSets); ++ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f)); ++ } + -+ public AsyncPlayerAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, -+ final ChangeCallback removeCallback) { -+ this(pooledHashSets, addCallback, removeCallback, null); -+ } -+ -+ public AsyncPlayerAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, -+ final ChangeCallback removeCallback, final ChangeSourceCallback changeSourceCallback) { -+ super(pooledHashSets, addCallback, removeCallback, changeSourceCallback); -+ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f)); -+ } ++ public AsyncPlayerAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, ++ final ChangeCallback removeCallback) { ++ this(pooledHashSets, addCallback, removeCallback, null); ++ } + ++ public AsyncPlayerAreaMap(final PooledLinkedHashSets pooledHashSets, final ChangeCallback addCallback, ++ final ChangeCallback removeCallback, final ChangeSourceCallback changeSourceCallback) { ++ super(pooledHashSets, addCallback, removeCallback, changeSourceCallback); ++ this.areaMap = new Long2ObjectOpenHashMapWrapper<>(new ConcurrentHashMap<>(1024, 0.7f)); ++ } +} diff --git a/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java b/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java new file mode 100644 -index 0000000000000000000000000000000000000000..c1929840254a3e6d721816f4a20415bea1742580 +index 0000000000000000000000000000000000000000..8b4a51ae41e99d41a1095333c2036efcc9a38973 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/util/IterableWrapper.java @@ -0,0 +1,20 @@ +package gg.pufferfish.pufferfish.util; + +import java.util.Iterator; ++ +import org.jetbrains.annotations.NotNull; + +public class IterableWrapper implements Iterable { + -+ private final Iterator iterator; ++ private final Iterator iterator; + -+ public IterableWrapper(Iterator iterator) { -+ this.iterator = iterator; -+ } -+ -+ @NotNull -+ @Override -+ public Iterator iterator() { -+ return iterator; -+ } ++ public IterableWrapper(Iterator iterator) { ++ this.iterator = iterator; ++ } + ++ @NotNull ++ @Override ++ public Iterator iterator() { ++ return iterator; ++ } +} diff --git a/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java new file mode 100644 -index 0000000000000000000000000000000000000000..42cdc43d6b739973a0944f502089757247ee6c61 +index 0000000000000000000000000000000000000000..5578acce073cea8a60619e634b3862624c8a1ae8 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/util/Long2ObjectOpenHashMapWrapper.java -@@ -0,0 +1,40 @@ +@@ -0,0 +1,42 @@ +package gg.pufferfish.pufferfish.util; + +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; ++ +import java.util.Map; ++ +import org.jetbrains.annotations.Nullable; + +public class Long2ObjectOpenHashMapWrapper extends Long2ObjectOpenHashMap { + -+ private final Map backingMap; ++ private final Map backingMap; + -+ public Long2ObjectOpenHashMapWrapper(Map map) { -+ backingMap = map; -+ } ++ public Long2ObjectOpenHashMapWrapper(Map map) { ++ backingMap = map; ++ } + -+ @Override -+ public V put(Long key, V value) { -+ return backingMap.put(key, value); -+ } ++ @Override ++ public V put(Long key, V value) { ++ return backingMap.put(key, value); ++ } + -+ @Override -+ public V get(Object key) { -+ return backingMap.get(key); -+ } ++ @Override ++ public V get(Object key) { ++ return backingMap.get(key); ++ } + -+ @Override -+ public V remove(Object key) { -+ return backingMap.remove(key); -+ } ++ @Override ++ public V remove(Object key) { ++ return backingMap.remove(key); ++ } + -+ @Nullable -+ @Override -+ public V putIfAbsent(Long key, V value) { -+ return backingMap.putIfAbsent(key, value); -+ } ++ @Nullable ++ @Override ++ public V putIfAbsent(Long key, V value) { ++ return backingMap.putIfAbsent(key, value); ++ } + -+ @Override -+ public int size() { -+ return backingMap.size(); -+ } ++ @Override ++ public int size() { ++ return backingMap.size(); ++ } +} diff --git a/patches/server/0004-Pufferfish-Sentry.patch b/patches/server/0004-Pufferfish-Sentry.patch index ddfde6dc..d31aae01 100644 --- a/patches/server/0004-Pufferfish-Sentry.patch +++ b/patches/server/0004-Pufferfish-Sentry.patch @@ -8,10 +8,10 @@ Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java new file mode 100644 -index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834733d0621 +index 0000000000000000000000000000000000000000..9ce570ddf314deda7a9980ab607af110a05aee16 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/sentry/PufferfishSentryAppender.java -@@ -0,0 +1,135 @@ +@@ -0,0 +1,137 @@ +package gg.pufferfish.pufferfish.sentry; + +import com.google.common.reflect.TypeToken; @@ -22,7 +22,9 @@ index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834 +import io.sentry.SentryLevel; +import io.sentry.protocol.Message; +import io.sentry.protocol.User; ++ +import java.util.Map; ++ +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Marker; @@ -32,124 +34,124 @@ index 0000000000000000000000000000000000000000..731ef11c7a025ae95ed8a757b530d834 +import org.apache.logging.log4j.core.filter.AbstractFilter; + +public class PufferfishSentryAppender extends AbstractAppender { -+ -+ private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger(PufferfishSentryAppender.class); -+ private static final Gson GSON = new Gson(); -+ -+ public PufferfishSentryAppender() { -+ super("PufferfishSentryAdapter", new SentryFilter(), null); -+ } -+ -+ @Override -+ public void append(LogEvent logEvent) { -+ if (logEvent.getThrown() != null && logEvent.getLevel().isMoreSpecificThan(Level.WARN)) { -+ try { -+ logException(logEvent); -+ } catch (Exception e) { -+ logger.warn("Failed to log event with sentry", e); -+ } -+ } else { -+ try { -+ logBreadcrumb(logEvent); -+ } catch (Exception e) { -+ logger.warn("Failed to log event with sentry", e); -+ } -+ } -+ } -+ -+ private void logException(LogEvent e) { -+ SentryEvent event = new SentryEvent(e.getThrown()); -+ -+ Message sentryMessage = new Message(); -+ sentryMessage.setMessage(e.getMessage().getFormattedMessage()); -+ -+ event.setThrowable(e.getThrown()); -+ event.setLevel(getLevel(e.getLevel())); -+ event.setLogger(e.getLoggerName()); -+ event.setTransaction(e.getLoggerName()); -+ event.setExtra("thread_name", e.getThreadName()); -+ -+ boolean hasContext = e.getContextData() != null; -+ -+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_playerid")) { -+ User user = new User(); -+ user.setId(e.getContextData().getValue("pufferfishsentry_playerid")); -+ user.setUsername(e.getContextData().getValue("pufferfishsentry_playername")); -+ event.setUser(user); -+ } -+ -+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_pluginname")) { -+ event.setExtra("plugin.name", e.getContextData().getValue("pufferfishsentry_pluginname")); -+ event.setExtra("plugin.version", e.getContextData().getValue("pufferfishsentry_pluginversion")); -+ event.setTransaction(e.getContextData().getValue("pufferfishsentry_pluginname")); -+ } -+ -+ if (hasContext && e.getContextData().containsKey("pufferfishsentry_eventdata")) { -+ Map eventFields = GSON.fromJson((String) e.getContextData().getValue("pufferfishsentry_eventdata"), new TypeToken>() {}.getType()); -+ if (eventFields != null) { -+ event.setExtra("event", eventFields); -+ } -+ } -+ -+ Sentry.captureEvent(event); -+ } -+ -+ private void logBreadcrumb(LogEvent e) { -+ Breadcrumb breadcrumb = new Breadcrumb(); -+ -+ breadcrumb.setLevel(getLevel(e.getLevel())); -+ breadcrumb.setCategory(e.getLoggerName()); -+ breadcrumb.setType(e.getLoggerName()); -+ breadcrumb.setMessage(e.getMessage().getFormattedMessage()); -+ -+ Sentry.addBreadcrumb(breadcrumb); -+ } -+ -+ private SentryLevel getLevel(Level level) { -+ switch (level.getStandardLevel()) { -+ case TRACE: -+ case DEBUG: -+ return SentryLevel.DEBUG; -+ case WARN: -+ return SentryLevel.WARNING; -+ case ERROR: -+ return SentryLevel.ERROR; -+ case FATAL: -+ return SentryLevel.FATAL; -+ case INFO: -+ default: -+ return SentryLevel.INFO; -+ } -+ } -+ -+ private static class SentryFilter extends AbstractFilter { -+ -+ @Override -+ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, String msg, -+ Object... params) { -+ return this.filter(logger.getName()); -+ } -+ -+ @Override -+ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, Object msg, Throwable t) { -+ return this.filter(logger.getName()); -+ } -+ -+ @Override -+ public Result filter(LogEvent event) { -+ return this.filter(event == null ? null : event.getLoggerName()); -+ } -+ -+ private Result filter(String loggerName) { -+ return loggerName != null && loggerName.startsWith("gg.castaway.pufferfish.sentry") ? Result.DENY -+ : Result.NEUTRAL; -+ } -+ -+ } ++ ++ private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger(PufferfishSentryAppender.class); ++ private static final Gson GSON = new Gson(); ++ ++ public PufferfishSentryAppender() { ++ super("PufferfishSentryAdapter", new SentryFilter(), null); ++ } ++ ++ @Override ++ public void append(LogEvent logEvent) { ++ if (logEvent.getThrown() != null && logEvent.getLevel().isMoreSpecificThan(Level.WARN)) { ++ try { ++ logException(logEvent); ++ } catch (Exception e) { ++ logger.warn("Failed to log event with sentry", e); ++ } ++ } else { ++ try { ++ logBreadcrumb(logEvent); ++ } catch (Exception e) { ++ logger.warn("Failed to log event with sentry", e); ++ } ++ } ++ } ++ ++ private void logException(LogEvent e) { ++ SentryEvent event = new SentryEvent(e.getThrown()); ++ ++ Message sentryMessage = new Message(); ++ sentryMessage.setMessage(e.getMessage().getFormattedMessage()); ++ ++ event.setThrowable(e.getThrown()); ++ event.setLevel(getLevel(e.getLevel())); ++ event.setLogger(e.getLoggerName()); ++ event.setTransaction(e.getLoggerName()); ++ event.setExtra("thread_name", e.getThreadName()); ++ ++ boolean hasContext = e.getContextData() != null; ++ ++ if (hasContext && e.getContextData().containsKey("pufferfishsentry_playerid")) { ++ User user = new User(); ++ user.setId(e.getContextData().getValue("pufferfishsentry_playerid")); ++ user.setUsername(e.getContextData().getValue("pufferfishsentry_playername")); ++ event.setUser(user); ++ } ++ ++ if (hasContext && e.getContextData().containsKey("pufferfishsentry_pluginname")) { ++ event.setExtra("plugin.name", e.getContextData().getValue("pufferfishsentry_pluginname")); ++ event.setExtra("plugin.version", e.getContextData().getValue("pufferfishsentry_pluginversion")); ++ event.setTransaction(e.getContextData().getValue("pufferfishsentry_pluginname")); ++ } ++ ++ if (hasContext && e.getContextData().containsKey("pufferfishsentry_eventdata")) { ++ Map eventFields = GSON.fromJson((String) e.getContextData().getValue("pufferfishsentry_eventdata"), new TypeToken>() { ++ }.getType()); ++ if (eventFields != null) { ++ event.setExtra("event", eventFields); ++ } ++ } ++ ++ Sentry.captureEvent(event); ++ } ++ ++ private void logBreadcrumb(LogEvent e) { ++ Breadcrumb breadcrumb = new Breadcrumb(); ++ ++ breadcrumb.setLevel(getLevel(e.getLevel())); ++ breadcrumb.setCategory(e.getLoggerName()); ++ breadcrumb.setType(e.getLoggerName()); ++ breadcrumb.setMessage(e.getMessage().getFormattedMessage()); ++ ++ Sentry.addBreadcrumb(breadcrumb); ++ } ++ ++ private SentryLevel getLevel(Level level) { ++ switch (level.getStandardLevel()) { ++ case TRACE: ++ case DEBUG: ++ return SentryLevel.DEBUG; ++ case WARN: ++ return SentryLevel.WARNING; ++ case ERROR: ++ return SentryLevel.ERROR; ++ case FATAL: ++ return SentryLevel.FATAL; ++ case INFO: ++ default: ++ return SentryLevel.INFO; ++ } ++ } ++ ++ private static class SentryFilter extends AbstractFilter { ++ ++ @Override ++ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, String msg, ++ Object... params) { ++ return this.filter(logger.getName()); ++ } ++ ++ @Override ++ public Result filter(Logger logger, org.apache.logging.log4j.Level level, Marker marker, Object msg, Throwable t) { ++ return this.filter(logger.getName()); ++ } ++ ++ @Override ++ public Result filter(LogEvent event) { ++ return this.filter(event == null ? null : event.getLoggerName()); ++ } ++ ++ private Result filter(String loggerName) { ++ return loggerName != null && loggerName.startsWith("gg.castaway.pufferfish.sentry") ? Result.DENY ++ : Result.NEUTRAL; ++ } ++ } +} diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..ab7a4acec52320c30623023c5fc9423e73f77a3b +index 0000000000000000000000000000000000000000..e9da86f5c655552ae3453e0c31ab1f1e63eb1ad8 --- /dev/null +++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryManager.java @@ -0,0 +1,39 @@ @@ -160,54 +162,77 @@ index 0000000000000000000000000000000000000000..ab7a4acec52320c30623023c5fc9423e +import org.apache.logging.log4j.Logger; + +public class SentryManager { -+ -+ private static final Logger logger = LogManager.getLogger(SentryManager.class); -+ -+ private SentryManager() { -+ -+ } -+ -+ private static boolean initialized = false; -+ -+ public static synchronized void init() { -+ if (initialized) { -+ return; -+ } -+ try { -+ initialized = true; -+ -+ Sentry.init(options -> { -+ options.setDsn(org.dreeam.leaf.LeafConfig.sentryDsn); -+ options.setMaxBreadcrumbs(100); -+ }); -+ -+ PufferfishSentryAppender appender = new PufferfishSentryAppender(); -+ appender.start(); -+ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender); -+ logger.info("Sentry logging started!"); -+ } catch (Exception e) { -+ logger.warn("Failed to initialize sentry!", e); -+ initialized = false; -+ } -+ } -+ -+} -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index d924db6378b2c60c7b96cf5c45a6d50a091f9790..b1fcd3588c22143f9852805a6cea3b6cf6c33a1f 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -168,4 +168,14 @@ public class LeafConfig { - - private static void network() { - } + ++ private static final Logger logger = LogManager.getLogger(SentryManager.class); ++ ++ private SentryManager() { ++ ++ } ++ ++ private static boolean initialized = false; ++ ++ public static synchronized void init() { ++ if (initialized) { ++ return; ++ } ++ try { ++ initialized = true; ++ ++ Sentry.init(options -> { ++ options.setDsn(org.dreeam.leaf.config.modules.misc.SentryDSN.sentryDsn); ++ options.setMaxBreadcrumbs(100); ++ }); ++ ++ PufferfishSentryAppender appender = new PufferfishSentryAppender(); ++ appender.start(); ++ ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()).addAppender(appender); ++ logger.info("Sentry logging started!"); ++ } catch (Exception e) { ++ logger.warn("Failed to initialize sentry!", e); ++ initialized = false; ++ } ++ } ++ ++} +diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/SentryDSN.java b/src/main/java/org/dreeam/leaf/config/modules/misc/SentryDSN.java +new file mode 100644 +index 0000000000000000000000000000000000000000..286af0f0e1d20d39e514e261dc8c0abd03284c5c +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/misc/SentryDSN.java +@@ -0,0 +1,36 @@ ++package org.dreeam.leaf.config.modules.misc; ++ ++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 SentryDSN implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.MISC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "sentry_dsn"; ++ } ++ ++ @ConfigInfo(baseName = "sentry-dsn") + public static String sentryDsn = ""; -+ private static void sentryDsn() { ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("misc.sentry_dsn", """ ++ Sentry DSN for improved error logging, leave blank to disable, ++ Obtain from https://sentry.io/welcome/ ++ """); ++ + String sentryEnvironment = System.getenv("SENTRY_DSN"); -+ String sentryConfig = getString("sentry-dsn", sentryDsn, "Sentry DSN for improved error logging, leave blank to disable", "Obtain from https://sentry.io/welcome/"); -+ sentryDsn = sentryEnvironment == null ? sentryConfig : sentryEnvironment; ++ sentryDsn = sentryEnvironment == null ? sentryDsn : sentryEnvironment; + if (sentryDsn != null && !sentryDsn.isBlank()) { + gg.pufferfish.pufferfish.sentry.SentryManager.init(); + } + } - } ++} diff --git a/patches/server/0005-Pufferfish-Optimize-mob-spawning.patch b/patches/server/0005-Pufferfish-Optimize-mob-spawning.patch index e30cb194..f5293b4d 100644 --- a/patches/server/0005-Pufferfish-Optimize-mob-spawning.patch +++ b/patches/server/0005-Pufferfish-Optimize-mob-spawning.patch @@ -33,14 +33,14 @@ index 9e7119152664e785e23f08e3a702f0bc60d817a0..a001fd51a7eb4ff97a84965679170f2d AtomicReference atomicreference = new AtomicReference(); Thread thread = new io.papermc.paper.util.TickThread(() -> { // Paper - rewrite chunk system diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index ee29ceff6804383edc229cd302ab07345f96658b..f20e75c358f48fc3962c236aab80ef1d378c7e8a 100644 +index bebafdf670ef1783ccae3b93fcda7d0eaef38d3e..b676d1605236b75cf6095a28c2a7a76f3466eea8 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -351,6 +351,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface DedicatedServer.LOGGER.info("JMX monitoring enabled"); } -+ if (org.dreeam.leaf.LeafConfig.enableAsyncMobSpawning) mobSpawnExecutor.start(); // Pufferfish ++ if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish return true; } } @@ -58,7 +58,7 @@ index d8a3b28b38f2ac62fbf0f87f8b5ff811873f8701..42869d35abb8d006fb720ca7190a770c public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor executor, BlockableEventLoop mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory, int viewDistance, boolean dsync) { diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 68ad7cb06d85c428f3560f95ed46bca32187e729..01fe42fea45a359714ca3fdeee05d85c561d0bb9 100644 +index 68ad7cb06d85c428f3560f95ed46bca32187e729..6587ce30d88983cb42822e6ff3e012047d3ce16d 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java @@ -76,6 +76,9 @@ public class ServerChunkCache extends ChunkSource { @@ -75,7 +75,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..01fe42fea45a359714ca3fdeee05d85c // Paper start - Optional per player mob spawns int naturalSpawnChunkCount = k; if ((this.spawnFriendlies || this.spawnEnemies) && this.level.paperConfig().entities.spawning.perPlayerMobSpawns) { // don't count mobs when animals and monsters are disabled -+ if (!org.dreeam.leaf.LeafConfig.enableAsyncMobSpawning) { // Pufferfish - moved down when async processing ++ if (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) { // Pufferfish - moved down when async processing // re-set mob counts for (ServerPlayer player : this.level.players) { // Paper start - per player mob spawning backoff @@ -111,7 +111,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..01fe42fea45a359714ca3fdeee05d85c chunk1.incrementInhabitedTime(j); - if (spawn && flagAndHasNaturalSpawn && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration // Gale - MultiPaper - skip unnecessary mob spawning computations - NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1); -+ if (spawn && flagAndHasNaturalSpawn && (!org.dreeam.leaf.LeafConfig.enableAsyncMobSpawning || _pufferfish_spawnCountsReady.get()) && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration // Gale - MultiPaper - skip unnecessary mob spawning computations // Pufferfish ++ if (spawn && flagAndHasNaturalSpawn && (!org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled || _pufferfish_spawnCountsReady.get()) && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration // Gale - MultiPaper - skip unnecessary mob spawning computations // Pufferfish + NaturalSpawner.spawnForChunk(this.level, chunk1, lastSpawnState, this.spawnFriendlies, this.spawnEnemies, flag1); // Pufferfish } @@ -122,7 +122,7 @@ index 68ad7cb06d85c428f3560f95ed46bca32187e729..01fe42fea45a359714ca3fdeee05d85c } + + // Pufferfish start - optimize mob spawning -+ if (org.dreeam.leaf.LeafConfig.enableAsyncMobSpawning) { ++ if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) { + for (ServerPlayer player : this.level.players) { + // Paper start - per player mob spawning backoff + for (int ii = 0; ii < ServerPlayer.MOBCATEGORY_TOTAL_ENUMS; ii++) { @@ -170,28 +170,50 @@ index 4cdfc433df67afcd455422e9baf56f167dd712ae..57fcf3910f45ce371ac2e237b277b103 private void ensureActiveIsNotIterated() { // Paper - replace with better logic, do not delay removals -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index b1fcd3588c22143f9852805a6cea3b6cf6c33a1f..5d161351e7517acf57e98203bab8c9f9ab9d4005 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -163,7 +163,20 @@ public class LeafConfig { - private static void removal() { - } - -+ public static boolean enableAsyncMobSpawning = true; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/async/AsyncMobSpawning.java b/src/main/java/org/dreeam/leaf/config/modules/async/AsyncMobSpawning.java +new file mode 100644 +index 0000000000000000000000000000000000000000..67c575439f7d60046586972dfc3212bb36a3d033 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/async/AsyncMobSpawning.java +@@ -0,0 +1,41 @@ ++package org.dreeam.leaf.config.modules.async; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.DoNotLoad; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class AsyncMobSpawning implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.ASYNC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "async_mob_spawning"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++ @DoNotLoad + public static boolean asyncMobSpawningInitialized; - private static void performance() { -+ boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, -+ "Whether or not asynchronous mob spawning should be enabled.", -+ "On servers with many entities, this can improve performance by up to 15%. You must have", -+ "paper's per-player-mob-spawns setting set to true for this to work.", -+ "One quick note - this does not actually spawn mobs async (that would be very unsafe).", -+ "This just offloads some expensive calculations that are required for mob spawning."); ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("async.async_mob_spawning", """ ++ Whether or not asynchronous mob spawning should be enabled. ++ On servers with many entities, this can improve performance by up to 15%. You must have ++ paper's per-player-mob-spawns setting set to true for this to work. ++ One quick note - this does not actually spawn mobs async (that would be very unsafe). ++ This just offloads some expensive calculations that are required for mob spawning."""); ++ + // This prevents us from changing the value during a reload. + if (!asyncMobSpawningInitialized) { + asyncMobSpawningInitialized = true; -+ enableAsyncMobSpawning = asyncMobSpawning; ++ this.get("async.async_mob_spawning.enabled", enabled, config); + } - } - - private static void network() { ++ } ++} diff --git a/patches/server/0006-Pufferfish-Dynamic-Activation-of-Brain.patch b/patches/server/0006-Pufferfish-Dynamic-Activation-of-Brain.patch index 5d1d89cc..beca9cc1 100644 --- a/patches/server/0006-Pufferfish-Dynamic-Activation-of-Brain.patch +++ b/patches/server/0006-Pufferfish-Dynamic-Activation-of-Brain.patch @@ -42,7 +42,7 @@ index 1591e201ebca4354d5912d3f803f59759af1ba6e..98e666c69b51f7b4fec040b7abd9667d if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed entity.discard(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 68fe93725a37cb0f52401038c1bda141ba0a4068..daff07928b7087c9a3d5d426446316545a5b08b8 100644 +index 68fe93725a37cb0f52401038c1bda141ba0a4068..68b256e6b3086127ba440f348bcd9d5926e029af 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -503,6 +503,11 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @@ -51,7 +51,7 @@ index 68fe93725a37cb0f52401038c1bda141ba0a4068..daff07928b7087c9a3d5d42644631654 + // Pufferfish start + public boolean activatedPriorityReset = false; // DAB -+ public int activatedPriority = org.dreeam.leaf.LeafConfig.maximumActivationPrio; // golf score ++ public int activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; // golf score + // Pufferfish end + public float getBukkitYaw() { @@ -119,7 +119,7 @@ index 646d9a121d908a2fc3e4e302484dd5cd1bfc6804..e546ecdccde352502e26a8668eaaafe0 } diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java -index 5e7b978a3019bc31ef94c1c666a3abdf380ced5c..aae8e547996f9a9ce6a3e110b2fc17f94b69ad3c 100644 +index 5e7b978a3019bc31ef94c1c666a3abdf380ced5c..8cc0d90665e64c81b15fc8aa251f2682b197e9f2 100644 --- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java @@ -51,9 +51,12 @@ public class GoalSelector { @@ -128,7 +128,7 @@ index 5e7b978a3019bc31ef94c1c666a3abdf380ced5c..aae8e547996f9a9ce6a3e110b2fc17f9 // Paper start - public boolean inactiveTick() { + public boolean inactiveTick(int tickRate, boolean inactive) { // Pufferfish start -+ if (inactive && !org.dreeam.leaf.LeafConfig.dabEnabled) tickRate = 4; // reset to Paper's ++ if (inactive && !org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled) tickRate = 4; // reset to Paper's + tickRate = Math.min(tickRate, this.newGoalRate); this.curRate++; - return this.curRate % this.newGoalRate == 0; @@ -293,71 +293,75 @@ index 5a9d567fdcaa02cf91dac889949f4428987f6fdd..e6b5b7c58505f021dc042c2c40733add if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; } -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 825e5d0a155039d9d87eb2ff9ef025fcb69d874a..e4c0f914681cbe99ced38e02b8b072eb1fb00159 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -1,7 +1,9 @@ - package org.dreeam.leaf; - - import com.google.common.collect.ImmutableMap; -+import net.minecraft.core.registries.BuiltInRegistries; - import net.minecraft.server.MinecraftServer; -+import net.minecraft.world.entity.EntityType; - import org.bukkit.configuration.ConfigurationSection; - import org.bukkit.configuration.MemoryConfiguration; - import org.jetbrains.annotations.Nullable; -@@ -13,6 +15,7 @@ import java.io.File; - import java.io.IOException; - import java.lang.reflect.Method; - import java.lang.reflect.Modifier; -+import java.util.Collections; - import java.util.List; - import java.util.Map; - -@@ -165,6 +168,12 @@ public class LeafConfig { - - public static boolean enableAsyncMobSpawning = true; - public static boolean asyncMobSpawningInitialized; -+ public static boolean dabEnabled = true; -+ public static int startDistance = 12; -+ public static int startDistanceSquared; -+ public static int maximumActivationPrio = 20; -+ public static int activationDistanceMod = 8; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java b/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2769eba9841ec866265e814e16f930a5e76de810 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/DynamicActivationofBrain.java +@@ -0,0 +1,61 @@ ++package org.dreeam.leaf.config.modules.opt; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.world.entity.EntityType; ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.DoNotLoad; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++import java.util.Collections; ++import java.util.List; ++ ++public class DynamicActivationofBrain implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "dab"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++ @ConfigInfo(baseName = "start-distance", comments = """ ++ This value determines how far away an entity has to be ++ from the player to start being effected by DEAR.""") ++ public static int startDistance = 12; ++ @DoNotLoad ++ public static int startDistanceSquared; ++ @ConfigInfo(baseName = "max-tick-freq", comments = """ ++ This value defines how often in ticks, the furthest entity ++ will get their pathfinders and behaviors ticked. 20 = 1s""") ++ public static int maximumActivationPrio = 20; ++ @ConfigInfo(baseName = "activation-dist-mod", comments = """ ++ This value defines how much distance modifies an entity's ++ tick frequency. freq = (distanceToPlayer^2) / (2^value)", ++ If you want further away entities to tick less often, use 7. ++ If you want further away entities to tick more often, try 9.""") ++ public static int activationDistanceMod = 8; ++ @ConfigInfo(baseName = "blacklisted-entities", comments = "A list of entities to ignore for activation") ++ public static List blackedEntities = Collections.emptyList(); ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("performance.dab", """ ++ Optimizes entity brains when ++ they're far away from the player"""); + - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -177,6 +186,27 @@ public class LeafConfig { - asyncMobSpawningInitialized = true; - enableAsyncMobSpawning = asyncMobSpawning; - } -+ dabEnabled = getBoolean("performance.dab.enabled", "dab.enabled", dabEnabled); -+ startDistance = getInt("performance.dab.start-distance", "dab.start-distance", startDistance, -+ "This value determines how far away an entity has to be", -+ "from the player to start being effected by DEAR."); + startDistanceSquared = startDistance * startDistance; -+ maximumActivationPrio = getInt("performance.dab.max-tick-freq", "dab.max-tick-freq", maximumActivationPrio, -+ "This value defines how often in ticks, the furthest entity", -+ "will get their pathfinders and behaviors ticked. 20 = 1s"); -+ activationDistanceMod = getInt("performance.dab.activation-dist-mod", "dab.activation-dist-mod", activationDistanceMod, -+ "This value defines how much distance modifies an entity's", -+ "tick frequency. freq = (distanceToPlayer^2) / (2^value)", -+ "If you want further away entities to tick less often, use 7.", -+ "If you want further away entities to tick more often, try 9."); + for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { + entityType.dabEnabled = true; // reset all, before setting the ones to true + } -+ getStringList("performance.dab.blacklisted-entities", "dab.blacklisted-entities", Collections.emptyList(), "A list of entities to ignore for activation") -+ .forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> { -+ entityType.dabEnabled = false; -+ }, () -> MinecraftServer.LOGGER.warn("Unknown entity \"{}\"", name))); -+ setComment("performance.dab", "Optimizes entity brains when", "they're far away from the player"); - } - - private static void network() { ++ blackedEntities.forEach(name -> EntityType.byString(name).ifPresentOrElse(entityType -> ++ entityType.dabEnabled = false, () -> MinecraftServer.LOGGER.warn("Unknown entity \"{}\"", name))); ++ } ++} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 1cff8378c4939af4bbe300e5d6428539e75218ae..2833c1ebc3a4d0e268527d1fcf2c74b5b5038c82 100644 +index 1cff8378c4939af4bbe300e5d6428539e75218ae..0735af396aa89b6ea7d5565d91f070fac90f7da1 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -40,6 +40,9 @@ import net.minecraft.world.level.Level; @@ -376,17 +380,17 @@ index 1cff8378c4939af4bbe300e5d6428539e75218ae..2833c1ebc3a4d0e268527d1fcf2c74b5 ActivationRange.activateEntity(entity); + + // Pufferfish start -+ if (org.dreeam.leaf.LeafConfig.dabEnabled && entity.getType().dabEnabled) { ++ if (org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.enabled && entity.getType().dabEnabled) { + if (!entity.activatedPriorityReset) { + entity.activatedPriorityReset = true; -+ entity.activatedPriority = org.dreeam.leaf.LeafConfig.maximumActivationPrio; ++ entity.activatedPriority = org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.maximumActivationPrio; + } + Vec3 playerVec = player.position(); + Vec3 entityVec = entity.position(); + double diffX = playerVec.x - entityVec.x, diffY = playerVec.y - entityVec.y, diffZ = playerVec.z - entityVec.z; + int squaredDistance = (int) (diffX * diffX + diffY * diffY + diffZ * diffZ); -+ entity.activatedPriority = squaredDistance > org.dreeam.leaf.LeafConfig.startDistanceSquared ? -+ Math.max(1, Math.min(squaredDistance >> org.dreeam.leaf.LeafConfig.activationDistanceMod, entity.activatedPriority)) : ++ entity.activatedPriority = squaredDistance > org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.startDistanceSquared ? ++ Math.max(1, Math.min(squaredDistance >> org.dreeam.leaf.config.modules.opt.DynamicActivationofBrain.activationDistanceMod, entity.activatedPriority)) : + 1; + } else { + entity.activatedPriority = 1; diff --git a/patches/server/0007-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch b/patches/server/0007-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch index 46da5198..9e5dde50 100644 --- a/patches/server/0007-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch +++ b/patches/server/0007-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch @@ -7,7 +7,7 @@ Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index b7d2d19f029c6fdc6091c9f60278a528885e17f8..8db706677eaa1bb4fedeae4679b81fe57e797cab 100644 +index b7d2d19f029c6fdc6091c9f60278a528885e17f8..11b1b96201af3ef4e88150411bcd9b95e75b3bfa 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -223,11 +223,13 @@ public abstract class Mob extends LivingEntity implements Targeting { @@ -20,31 +20,43 @@ index b7d2d19f029c6fdc6091c9f60278a528885e17f8..8db706677eaa1bb4fedeae4679b81fe5 public void inactiveTick() { super.inactiveTick(); - if (this.goalSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priroity -+ boolean isThrottled = org.dreeam.leaf.LeafConfig.throttleInactiveGoalSelectorTick && _pufferfish_inactiveTickDisableCounter++ % 20 != 0; // Pufferfish - throttle inactive goal selector ticking ++ boolean isThrottled = org.dreeam.leaf.config.modules.opt.ThrottleInactiveGoalSelectorTick.enabled && _pufferfish_inactiveTickDisableCounter++ % 20 != 0; // Pufferfish - throttle inactive goal selector ticking + if (this.goalSelector.inactiveTick(this.activatedPriority, true) && !isThrottled) { // Pufferfish - pass activated priroity // Pufferfish - throttle inactive goal selector ticking this.goalSelector.tick(); } if (this.targetSelector.inactiveTick(this.activatedPriority, true)) { // Pufferfish - pass activated priority -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index e4c0f914681cbe99ced38e02b8b072eb1fb00159..141754b5b4361905e22dd9276a921cfc4847b0c4 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -173,7 +173,7 @@ public class LeafConfig { - public static int startDistanceSquared; - public static int maximumActivationPrio = 20; - public static int activationDistanceMod = 8; -- -+ public static boolean throttleInactiveGoalSelectorTick = true; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -207,6 +207,9 @@ public class LeafConfig { - entityType.dabEnabled = false; - }, () -> MinecraftServer.LOGGER.warn("Unknown entity \"{}\"", name))); - setComment("performance.dab", "Optimizes entity brains when", "they're far away from the player"); -+ throttleInactiveGoalSelectorTick = getBoolean("performance.inactive-goal-selector-throttle", "inactive-goal-selector-throttle", throttleInactiveGoalSelectorTick, -+ "Throttles the AI goal selector in entity inactive ticks.", -+ "This can improve performance by a few percent, but has minor gameplay implications."); - } - - private static void network() { +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/ThrottleInactiveGoalSelectorTick.java b/src/main/java/org/dreeam/leaf/config/modules/opt/ThrottleInactiveGoalSelectorTick.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ad6354ca7c7f8c96831fe4ef8fc624b4bcb90af5 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/ThrottleInactiveGoalSelectorTick.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 ThrottleInactiveGoalSelectorTick implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "inactive_goal_selector_throttle"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("performance.inactive_goal_selector_throttle", """ ++ Throttles the AI goal selector in entity inactive ticks. ++ This can improve performance by a few percent, but has minor gameplay implications."""); ++ } ++} diff --git a/patches/server/0008-Pufferfish-Entity-TTL.patch b/patches/server/0008-Pufferfish-Entity-TTL.patch index 15494291..9db83094 100644 --- a/patches/server/0008-Pufferfish-Entity-TTL.patch +++ b/patches/server/0008-Pufferfish-Entity-TTL.patch @@ -7,7 +7,7 @@ Original license: GPL v3 Original project: https://github.com/pufferfish-gg/Pufferfish diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index be371242518c4027e03e233db1bd0a9192e9edc9..7eff987694d03ccfa687114ee4f2650a7f83a1ea 100644 +index 68b256e6b3086127ba440f348bcd9d5926e029af..3f3ae7439bd2796870e7cdffa37b097d9c54cfd2 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -814,6 +814,12 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S @@ -35,42 +35,48 @@ index d86c34111ede6a1454dde5e7223d7caf2ab39ef3..dc11683ee4d8a6b7a1c42bcae36dc6e8 @Nullable private String descriptionId; @Nullable -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 9a11228726c9a489181fc8a0c511ea83cdcf0f6e..9299d2fe1cda71b6881fd8bd65d3d74b1189a196 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -17,6 +17,7 @@ import java.lang.reflect.Method; - import java.lang.reflect.Modifier; - import java.util.Collections; - import java.util.List; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/EntityTTL.java b/src/main/java/org/dreeam/leaf/config/modules/opt/EntityTTL.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8530cca54105d74f94a2c7e2ed7eab9b6f2f06f0 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/EntityTTL.java +@@ -0,0 +1,39 @@ ++package org.dreeam.leaf.config.modules.opt; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.world.entity.EntityType; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ +import java.util.Locale; - import java.util.Map; - - public class LeafConfig { -@@ -174,6 +175,7 @@ public class LeafConfig { - public static int maximumActivationPrio = 20; - public static int activationDistanceMod = 8; - public static boolean throttleInactiveGoalSelectorTick = true; -+ public static Map projectileTimeouts; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -210,6 +212,18 @@ public class LeafConfig { - throttleInactiveGoalSelectorTick = getBoolean("performance.inactive-goal-selector-throttle", "inactive-goal-selector-throttle", throttleInactiveGoalSelectorTick, - "Throttles the AI goal selector in entity inactive ticks.", - "This can improve performance by a few percent, but has minor gameplay implications."); ++ ++public class EntityTTL implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "entity_timeouts"; ++ } ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("performance.entity_timeouts", """ ++ These values define a entity's maximum lifespan. If an ++ entity is in this list and it has survived for longer than ++ that number of ticks, then it will be removed. Setting a value to ++ -1 disables this feature."""); ++ + // Set some defaults -+ getInt("performance.entity_timeouts.SNOWBALL", -1); -+ getInt("performance.entity_timeouts.LLAMA_SPIT", -1); -+ setComment("entity_timeouts", -+ "These values define a entity's maximum lifespan. If an", -+ "entity is in this list and it has survived for longer than", -+ "that number of ticks, then it will be removed. Setting a value to", -+ "-1 disables this feature."); ++ this.get("performance.entity_timeouts.SNOWBALL", -1, config); ++ this.get("performance.entity_timeouts.LLAMA_SPIT", -1, config); + for (EntityType entityType : BuiltInRegistries.ENTITY_TYPE) { + String type = EntityType.getKey(entityType).getPath().toUpperCase(Locale.ROOT); -+ entityType.ttl = config.getInt("entity_timeouts." + type, -1); ++ entityType.ttl = this.get("performance.entity_timeouts." + type, -1, config); + } - } - - private static void network() { ++ } ++} diff --git a/patches/server/0009-Purpur-Server-Changes.patch b/patches/server/0009-Purpur-Server-Changes.patch index f169cd22..91dd3c07 100644 --- a/patches/server/0009-Purpur-Server-Changes.patch +++ b/patches/server/0009-Purpur-Server-Changes.patch @@ -30,21 +30,23 @@ MC-121706-Fix-mobs-not-looking-up-and-down-when-stra.patch Fire-Immunity-API.patch diff --git a/build.gradle.kts b/build.gradle.kts -index c8ba9702926c55f783d35a7df9b3cfc3af27f005..45d18d5a21f8bc8c54856e0222abd83ad5f419d6 100644 +index a53b30ab2315fc0b2ce07d9449042842e6ca3b39..e1f45b67457ba151a94b4709aeabc7a2fe730c28 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -63,6 +63,10 @@ dependencies { - } - // Leaf end +@@ -59,6 +59,12 @@ dependencies { + runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") + runtimeOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18") -+ implementation("org.mozilla:rhino-runtime:1.7.14") // Purpur -+ implementation("org.mozilla:rhino-engine:1.7.14") // Purpur -+ implementation("dev.omega24:upnp4j:1.0") // Purpur ++ // Purpur start ++ implementation("org.mozilla:rhino-runtime:1.7.14") ++ implementation("org.mozilla:rhino-engine:1.7.14") ++ implementation("dev.omega24:upnp4j:1.0") ++ // Purpur end + testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testImplementation("org.hamcrest:hamcrest:2.2") -@@ -178,7 +182,7 @@ fun TaskContainer.registerRunTask( +@@ -174,7 +180,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -936,7 +938,7 @@ index 1b459a8ee8a6bc039e742d65796bc76660a1c765..599172b994d75484f7c7e0ce6d3d3d77 itemstack1.setCount(1); entityitem = entityplayer.drop(itemstack1, false, false, false); // CraftBukkit - SPIGOT-2942: Add boolean to call event diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index f20e75c358f48fc3962c236aab80ef1d378c7e8a..5cac0f1565539b5723cee6394221f11ff6c9920a 100644 +index b676d1605236b75cf6095a28c2a7a76f3466eea8..8749010decf3a7d9490762c7641530bd91f4e19c 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java @@ -98,6 +98,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -947,7 +949,7 @@ index f20e75c358f48fc3962c236aab80ef1d378c7e8a..5cac0f1565539b5723cee6394221f11f new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start(); /* jline.console.ConsoleReader bufferedreader = DedicatedServer.this.reader; -@@ -223,6 +224,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -224,6 +225,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command GaleCommands.registerCommands(this); // Gale - Gale commands - register commands com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics @@ -997,7 +999,7 @@ index f20e75c358f48fc3962c236aab80ef1d378c7e8a..5cac0f1565539b5723cee6394221f11f @@ -352,6 +386,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface } - if (org.dreeam.leaf.LeafConfig.enableAsyncMobSpawning) mobSpawnExecutor.start(); // Pufferfish + if (org.dreeam.leaf.config.modules.async.AsyncMobSpawning.enabled) mobSpawnExecutor.start(); // Pufferfish + org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur + if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur return true; @@ -2440,7 +2442,7 @@ index 1f9e0c139988c4c44a26552881647d36965aa4fa..b8d612d22aca74a08b53393c0723a2ae @Override diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 5cbd7f2f5f8cff4b2f59387d2d2214f1db6620b9..6096528056dca47fd139fe27d1e0a5b919270aa6 100644 +index 3f3ae7439bd2796870e7cdffa37b097d9c54cfd2..6c70002119d40a0074319d2ee85862930d6abf0e 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -159,7 +159,7 @@ import org.bukkit.plugin.PluginManager; @@ -3199,7 +3201,7 @@ index 4f749c3634b63926a7672716481ae5a650040ab2..f70f58937eedd69ebb46fefb367ab253 }); } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 8db706677eaa1bb4fedeae4679b81fe57e797cab..4f045c799087709ef3a39983533776e9fedd00eb 100644 +index 11b1b96201af3ef4e88150411bcd9b95e75b3bfa..2f06a3226f05797d6e2427e444a568bf06c67e3a 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -66,6 +66,7 @@ import net.minecraft.world.item.ProjectileWeaponItem; @@ -24735,7 +24737,7 @@ index 0000000000000000000000000000000000000000..b7586f494528f30eb0da82420d3bcf5b + } +} diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 2833c1ebc3a4d0e268527d1fcf2c74b5b5038c82..d88d553fc5b9d9e13d24d94275ed5b9c91d5e41f 100644 +index 0735af396aa89b6ea7d5565d91f070fac90f7da1..c6c58c398b2ce4741301afaa04d2ba2dbee475d4 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -15,6 +15,7 @@ import net.minecraft.world.entity.ambient.AmbientCreature; diff --git a/patches/server/0010-Purpur-Configurable-server-mod-name.patch b/patches/server/0010-Purpur-Configurable-server-mod-name.patch index 3f6283b7..95a1c32d 100644 --- a/patches/server/0010-Purpur-Configurable-server-mod-name.patch +++ b/patches/server/0010-Purpur-Configurable-server-mod-name.patch @@ -7,7 +7,7 @@ Original license: MIT Original project: https://github.com/PurpurMC/Purpur diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 330f0f66ab16c88b2a827f09f99c42671a53a410..f9952df410ca862ee6573abaaa1c9b5634bdad5e 100644 +index 330f0f66ab16c88b2a827f09f99c42671a53a410..16d3fc610fc15da85f3b0652e835d196c010c89d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1845,7 +1845,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop +Date: Sun, 14 Jan 2024 05:14:09 -0500 +Subject: [PATCH] Configurable server GUI name + + +diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java +index 7f07ffab0835d45d4d170fe171d7fa996d5913d9..41fa7b642708d15292879d583a247fd820d5ed03 100644 +--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java ++++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java +@@ -56,7 +56,7 @@ public class MinecraftServerGui extends JComponent { + ; + } + +- final JFrame jframe = new JFrame("Purpur Minecraft server"); // Purpur ++ final JFrame jframe = new JFrame(org.dreeam.leaf.config.modules.misc.ServerBrand.serverGUIName); // Purpur // Leaf - Configurable server GUI name + final MinecraftServerGui servergui = new MinecraftServerGui(server); + + jframe.setDefaultCloseOperation(2); +@@ -64,7 +64,7 @@ public class MinecraftServerGui extends JComponent { + jframe.pack(); + jframe.setLocationRelativeTo((Component) null); + jframe.setVisible(true); +- jframe.setName("Purpur Minecraft server"); // Paper - Improve ServerGUI // Purpur ++ jframe.setName(org.dreeam.leaf.config.modules.misc.ServerBrand.serverGUIName); // Paper - Improve ServerGUI // Purpur // Leaf - Configurable server GUI name + + // Paper start - Improve ServerGUI + try { +@@ -76,7 +76,7 @@ public class MinecraftServerGui extends JComponent { + jframe.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent windowevent) { + if (!servergui.isClosing.getAndSet(true)) { +- jframe.setTitle("Purpur Minecraft server - shutting down!"); // Purpur ++ jframe.setTitle(org.dreeam.leaf.config.modules.misc.ServerBrand.serverGUIName + " - shutting down!"); // Purpur // Leaf - Configurable server GUI name + server.halt(true); + servergui.runFinalizers(); + } +diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/ServerBrand.java b/src/main/java/org/dreeam/leaf/config/modules/misc/ServerBrand.java +index eb7b7b7d2d51173ce1297d618a586d4d686f8041..1e2afef02409dbcb26171b2cbbe905b7e6e80698 100644 +--- a/src/main/java/org/dreeam/leaf/config/modules/misc/ServerBrand.java ++++ b/src/main/java/org/dreeam/leaf/config/modules/misc/ServerBrand.java +@@ -18,4 +18,7 @@ public class ServerBrand implements IConfigModule { + + @ConfigInfo(baseName = "server-mod-name") + public static String serverModName = "Leaf"; ++ ++ @ConfigInfo(baseName = "server-gui-name") ++ public static String serverGUIName = "Leaf Console"; + } diff --git a/patches/server/0011-Configurable-server-Gui-name.patch b/patches/server/0011-Configurable-server-Gui-name.patch deleted file mode 100644 index d8893abb..00000000 --- a/patches/server/0011-Configurable-server-Gui-name.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> -Date: Sun, 14 Jan 2024 05:14:09 -0500 -Subject: [PATCH] Configurable server Gui name - - -diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java -index 7f07ffab0835d45d4d170fe171d7fa996d5913d9..0f20cb3dcf4aac8a8c6cd7408808dec962869c1a 100644 ---- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java -+++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java -@@ -56,7 +56,7 @@ public class MinecraftServerGui extends JComponent { - ; - } - -- final JFrame jframe = new JFrame("Purpur Minecraft server"); // Purpur -+ final JFrame jframe = new JFrame(org.dreeam.leaf.LeafConfig.serverGuiName); // Purpur // Leaf - Configurable server Gui name - final MinecraftServerGui servergui = new MinecraftServerGui(server); - - jframe.setDefaultCloseOperation(2); -@@ -64,7 +64,7 @@ public class MinecraftServerGui extends JComponent { - jframe.pack(); - jframe.setLocationRelativeTo((Component) null); - jframe.setVisible(true); -- jframe.setName("Purpur Minecraft server"); // Paper - Improve ServerGUI // Purpur -+ jframe.setName(org.dreeam.leaf.LeafConfig.serverGuiName); // Paper - Improve ServerGUI // Purpur // Leaf - Configurable server Gui name - - // Paper start - Improve ServerGUI - try { -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 80a196442edbc6b4eb44bb6a405100871aea2f6a..c3c186a561442351ef7e1146ae09f3b5be900dbc 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -165,8 +165,10 @@ public class LeafConfig { - } - - public static String serverModName = "Leaf"; -+ public static String serverGuiName = "Leaf Console"; - private static void serverModName() { - serverModName = getString("server-mod-name", serverModName); -+ serverGuiName = getString("server-Gui-name", serverGuiName); - } - - private static void removal() { diff --git a/patches/server/0013-Bump-Dependencies.patch b/patches/server/0013-Bump-Dependencies.patch index 94eb69bf..5a1354f1 100644 --- a/patches/server/0013-Bump-Dependencies.patch +++ b/patches/server/0013-Bump-Dependencies.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Bump Dependencies diff --git a/build.gradle.kts b/build.gradle.kts -index 45d18d5a21f8bc8c54856e0222abd83ad5f419d6..e17498431aed5c8e683897035f7a172d71ddca96 100644 +index e1f45b67457ba151a94b4709aeabc7a2fe730c28..7a5933a2bb8cde20d4d147cc2665b2e65b881c35 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -22,9 +22,9 @@ dependencies { - } - // Gale end - project setup +@@ -25,9 +25,9 @@ dependencies { + implementation("com.electronwill.night-config:toml:3.6.7") // Leaf - Night config + // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") + implementation("org.jline:jline-terminal-jansi:3.25.1") // Leaf - Bump Dependencies @@ -20,7 +20,7 @@ index 45d18d5a21f8bc8c54856e0222abd83ad5f419d6..e17498431aed5c8e683897035f7a172d implementation("net.kyori:ansi:1.0.3") // Manually bump beyond above transitive dep /* Required to add the missing Log4j2Plugins.dat file from log4j-core -@@ -32,24 +32,26 @@ dependencies { +@@ -35,24 +35,26 @@ dependencies { all its classes to check if they are plugins. Scanning takes about 1-2 seconds so adding this speeds up the server start. */ @@ -57,9 +57,9 @@ index 45d18d5a21f8bc8c54856e0222abd83ad5f419d6..e17498431aed5c8e683897035f7a172d // Paper end - Use Velocity cipher runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6") -@@ -67,11 +69,15 @@ dependencies { - implementation("org.mozilla:rhino-engine:1.7.14") // Purpur - implementation("dev.omega24:upnp4j:1.0") // Purpur +@@ -65,11 +67,15 @@ dependencies { + implementation("dev.omega24:upnp4j:1.0") + // Purpur end - testImplementation("io.github.classgraph:classgraph:4.8.47") // Paper - mob goal test - testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") @@ -76,7 +76,7 @@ index 45d18d5a21f8bc8c54856e0222abd83ad5f419d6..e17498431aed5c8e683897035f7a172d } val craftbukkitPackageVersion = "1_20_R3" // Paper -@@ -263,3 +269,7 @@ sourceSets { +@@ -261,3 +267,7 @@ sourceSets { } } // Gale end - package license into jar diff --git a/patches/server/0014-Remove-Mojang-username-check.patch b/patches/server/0014-Remove-vanilla-username-check.patch similarity index 55% rename from patches/server/0014-Remove-Mojang-username-check.patch rename to patches/server/0014-Remove-vanilla-username-check.patch index ae0a46d7..4e595f2f 100644 --- a/patches/server/0014-Remove-Mojang-username-check.patch +++ b/patches/server/0014-Remove-vanilla-username-check.patch @@ -1,11 +1,11 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Wed, 12 Oct 2022 14:36:58 -0400 -Subject: [PATCH] Remove Mojang username check +Subject: [PATCH] Remove vanilla username check diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 4bd1d7c4328e13ae3e173836ced22125857bcae1..cd33d0b88543355d2f8018ef8ec719998362f526 100644 +index 4bd1d7c4328e13ae3e173836ced22125857bcae1..0f3ba1abb609562e92dd9eb0ab7a621b8ed2d09f 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -153,7 +153,11 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, @@ -13,27 +13,46 @@ index 4bd1d7c4328e13ae3e173836ced22125857bcae1..cd33d0b88543355d2f8018ef8ec71999 // Gale start - JettPack - reduce array allocations Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet", ArrayConstants.emptyObjectArray); - if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) Validate.validState(Player.isValidUsername(packet.name()), "Invalid characters in username", ArrayConstants.emptyObjectArray); // Paper - config username validation -+ // Leaf start - Remove Mojang's username check -+ if (!org.dreeam.leaf.LeafConfig.removeMojangUsernameCheck) { ++ // Leaf start - Remove Vanilla username check ++ if (!org.dreeam.leaf.config.modules.misc.RemoveVanillaUsernameCheck.enabled) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.performUsernameValidation && !this.iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation) Validate.validState(Player.isValidUsername(packet.name()), "Invalid characters in username", ArrayConstants.emptyObjectArray); // Paper - config username validation + } + // Leaf end // Gale end - JettPack - reduce array allocations this.requestedUsername = packet.name(); GameProfile gameprofile = this.server.getSingleplayerProfile(); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index c3c186a561442351ef7e1146ae09f3b5be900dbc..30de4fc564ba263c55b16e8b551b643e09c860be 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -171,7 +171,11 @@ public class LeafConfig { - serverGuiName = getString("server-Gui-name", serverGuiName); - } - -+ public static boolean removeMojangUsernameCheck = true; - private static void removal() { -+ removeMojangUsernameCheck = getBoolean("remove-Mojang-username-check", removeMojangUsernameCheck, -+ "Remove username check of Mojang", -+ "enabling all characters as username"); - } - - public static boolean enableAsyncMobSpawning = true; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2dcdf5adff80f63499e6d160ff24313653cfb315 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveVanillaUsernameCheck.java +@@ -0,0 +1,29 @@ ++package org.dreeam.leaf.config.modules.misc; ++ ++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 RemoveVanillaUsernameCheck implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.MISC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "remove_vanilla_username_check"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("misc.remove_vanilla_username_check", """ ++ Remove Vanilla username check ++ allowing all characters as username"""); ++ } ++} diff --git a/patches/server/0015-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch b/patches/server/0015-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch index 0d7f14d9..8666d7e6 100644 --- a/patches/server/0015-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch +++ b/patches/server/0015-Remove-Spigot-Check-for-Broken-BungeeCord-Configurat.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove Spigot Check for Broken BungeeCord Configurations diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java -index 115877acb37da061a834ce8a7f9919383bb41abd..9b924907162e2bb11861539ef3fae03424819673 100644 +index dec666713a1d3b5e3f2aa4bcbe8094ade8be1b05..c72620cce4ca7b6751b00f42b6c3d8f5d9a19132 100644 --- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java @@ -147,7 +147,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL @@ -13,26 +13,42 @@ index 115877acb37da061a834ce8a7f9919383bb41abd..9b924907162e2bb11861539ef3fae034 this.connection.spoofedProfile = ServerHandshakePacketListenerImpl.gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); } - } else if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { -+ } else if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) && !(org.dreeam.leaf.LeafConfig.removeSpigotCheckBungeeConfig)) { // Leaf - Remove Spigot check for broken BungeeCord configurations ++ } else if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) && !(org.dreeam.leaf.config.modules.misc.RemoveSpigotCheckBungee.enabled)) { // Leaf - Remove Spigot check for broken BungeeCord configurations Component chatmessage = Component.literal("Unknown data in login hostname, did you forget to enable BungeeCord in spigot.yml?"); this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); this.connection.disconnect(chatmessage); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 96db490f4d3039953bab55e61d608679275cbfa7..4660e1732f8f2e2c236b3d6c3c60e5122daa1172 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -172,10 +172,14 @@ public class LeafConfig { - } - - public static boolean removeMojangUsernameCheck = true; -+ public static boolean removeSpigotCheckBungeeConfig = true; - private static void removal() { - removeMojangUsernameCheck = getBoolean("remove-Mojang-username-check", removeMojangUsernameCheck, - "Remove username check of Mojang", - "enabling all characters as username"); -+ removeSpigotCheckBungeeConfig = getBoolean("remove-Spigot-check-bungee-config", removeSpigotCheckBungeeConfig, -+ "Enable player enter backend server through proxy", -+ "without backend server enabling its bungee mode"); - } - - public static boolean enableAsyncMobSpawning = true; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveSpigotCheckBungee.java b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveSpigotCheckBungee.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bca9e66deb5afd7ea25ad2532a207771ab93084f +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/misc/RemoveSpigotCheckBungee.java +@@ -0,0 +1,29 @@ ++package org.dreeam.leaf.config.modules.misc; ++ ++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 RemoveSpigotCheckBungee implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.MISC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "remove_spigot_check_bungee_config"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("misc.remove_spigot_check_bungee_config", """ ++ Enable player enter backend server through proxy ++ without backend server enabling its bungee mode"""); ++ } ++} diff --git a/patches/server/0016-Remove-UseItemOnPacket-Too-Far-Check.patch b/patches/server/0016-Remove-UseItemOnPacket-Too-Far-Check.patch index ce5235b4..4b7f449d 100644 --- a/patches/server/0016-Remove-UseItemOnPacket-Too-Far-Check.patch +++ b/patches/server/0016-Remove-UseItemOnPacket-Too-Far-Check.patch @@ -7,7 +7,7 @@ This Check is added in 1.17.x -> 1.18.x update by Mojang. By removing this check, it enable hackers to use some modules of hack clients. diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1d0c724137c002801b3dbb239278f2a1c82c1d77..58fe904de3b3f3b9a823b550a3ad143eac26e8bb 100644 +index 1d0c724137c002801b3dbb239278f2a1c82c1d77..8895e7d35af8650503853b6fc7432f66e4f333db 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -2007,7 +2007,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -15,30 +15,38 @@ index 1d0c724137c002801b3dbb239278f2a1c82c1d77..58fe904de3b3f3b9a823b550a3ad143e double d0 = 1.0000001D; - if (Math.abs(vec3d2.x()) < 1.0000001D && Math.abs(vec3d2.y()) < 1.0000001D && Math.abs(vec3d2.z()) < 1.0000001D) { -+ if ((Math.abs(vec3d2.x()) < org.dreeam.leaf.LeafConfig.maxUseItemDistance && Math.abs(vec3d2.y()) < org.dreeam.leaf.LeafConfig.maxUseItemDistance && Math.abs(vec3d2.z()) < org.dreeam.leaf.LeafConfig.maxUseItemDistance) || org.dreeam.leaf.LeafConfig.removeUseItemOnPacketTooFar) { // Leaf - Remove UseItemOnPacket Too Far Check and make it configurable ++ if ((Math.abs(vec3d2.x()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance && Math.abs(vec3d2.y()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance && Math.abs(vec3d2.z()) < org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.maxUseItemDistance) || org.dreeam.leaf.config.modules.gameplay.ConfigurableMaxUseItemDistance.removeUseItemOnPacketTooFarCheck) { // Leaf - Remove UseItemOnPacket Too Far Check and make it configurable Direction enumdirection = movingobjectpositionblock.getDirection(); this.player.resetLastActionTime(); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index e88cfb1a48f253e2f6360b2ff00bd36b58af6a23..df16a84545dd726e6f4eaaff13232e4d95dd11af 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -173,6 +173,8 @@ public class LeafConfig { - - public static boolean removeMojangUsernameCheck = true; - public static boolean removeSpigotCheckBungeeConfig = true; -+ public static boolean removeUseItemOnPacketTooFar = false; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/ConfigurableMaxUseItemDistance.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/ConfigurableMaxUseItemDistance.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9275e1861adb1ad2e313fcf0ca76a29824358339 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/ConfigurableMaxUseItemDistance.java +@@ -0,0 +1,25 @@ ++package org.dreeam.leaf.config.modules.gameplay; ++ ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class ConfigurableMaxUseItemDistance implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.MISC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "configurable_max_use_item_distance"; ++ } ++ ++ @ConfigInfo(baseName = "max-use-item-distance", comments = "The max distance of UseItem for players") + public static double maxUseItemDistance = 1.0000001D; - private static void removal() { - removeMojangUsernameCheck = getBoolean("remove-Mojang-username-check", removeMojangUsernameCheck, - "Remove username check of Mojang", -@@ -180,6 +182,9 @@ public class LeafConfig { - removeSpigotCheckBungeeConfig = getBoolean("remove-Spigot-check-bungee-config", removeSpigotCheckBungeeConfig, - "Enable player enter backend server through proxy", - "without backend server enabling its bungee mode"); -+ removeUseItemOnPacketTooFar = getBoolean("remove-UseItemOnPacket-too-far-check", removeUseItemOnPacketTooFar, -+ "To enable this, players can use some packet modules with hack clients and the NoCom Exploit!!"); -+ maxUseItemDistance = getDouble("max-UseItem-distance", maxUseItemDistance, "The max distance of UseItem for players"); - } - - public static boolean enableAsyncMobSpawning = true; ++ @ConfigInfo(baseName = "remove-max-distance-check", comments = """ ++ To enable this, players can use some packet modules ++ with hack clients and the NoCom Exploit!!""") ++ public static boolean removeUseItemOnPacketTooFarCheck = false; ++} diff --git a/patches/server/0020-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch b/patches/server/0020-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch index 4c79e371..d06eba49 100644 --- a/patches/server/0020-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch +++ b/patches/server/0020-KeYi-Add-an-option-for-spigot-item-merging-mechanism.patch @@ -7,7 +7,7 @@ Original license: MIT Original project: https://github.com/KeYiMC/KeYi diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -index 2c19d6687e1554373e4c7f43a8fec8e770942f50..7f1803d073ba3a4be2c93c52dd1775f678ced7ae 100644 +index 2c19d6687e1554373e4c7f43a8fec8e770942f50..fbee057a90fb47f4b31388cdff052fbaf04b33d6 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -349,7 +349,7 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -15,27 +15,34 @@ index 2c19d6687e1554373e4c7f43a8fec8e770942f50..7f1803d073ba3a4be2c93c52dd1775f6 if (Objects.equals(this.target, other.target) && ItemEntity.areMergable(itemstack, itemstack1)) { - if (true || itemstack1.getCount() < itemstack.getCount()) { // Spigot -+ if (org.dreeam.leaf.LeafConfig.useSpigotItemMergingMechanism || itemstack1.getCount() < itemstack.getCount()) { // Spigot // Leaf - KeYi - Configurable spigot item merging mechanism ++ if (org.dreeam.leaf.config.modules.gameplay.UseSpigotItemMergingMech.enabled || itemstack1.getCount() < itemstack.getCount()) { // Spigot // Leaf - KeYi - Configurable spigot item merging mechanism ItemEntity.merge(this, itemstack, other, itemstack1); } else { ItemEntity.merge(other, itemstack1, this, itemstack); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index df16a84545dd726e6f4eaaff13232e4d95dd11af..e81cb3b303a53b4d2edb80563be806c8ef9c8bed 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -196,6 +196,7 @@ public class LeafConfig { - public static int activationDistanceMod = 8; - public static boolean throttleInactiveGoalSelectorTick = true; - public static Map projectileTimeouts; -+ public static boolean useSpigotItemMergingMechanism = true; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -244,6 +245,7 @@ public class LeafConfig { - String type = EntityType.getKey(entityType).getPath().toUpperCase(Locale.ROOT); - entityType.ttl = config.getInt("entity_timeouts." + type, -1); - } -+ useSpigotItemMergingMechanism = getBoolean("performance.use-spigot-item-merging-mechanism", useSpigotItemMergingMechanism); - } - - private static void network() { +diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/UseSpigotItemMergingMech.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/UseSpigotItemMergingMech.java +new file mode 100644 +index 0000000000000000000000000000000000000000..68c80a2019e1f142baa60b17f87d247c2a4a1d03 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/UseSpigotItemMergingMech.java +@@ -0,0 +1,21 @@ ++package org.dreeam.leaf.config.modules.gameplay; ++ ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class UseSpigotItemMergingMech implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "use-spigot-item-merging-mechanism"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++} diff --git a/patches/server/0023-Rail-Optimization-optimized-PoweredRailBlock-logic.patch b/patches/server/0023-Rail-Optimization-optimized-PoweredRailBlock-logic.patch index e42d4754..effdf7b7 100644 --- a/patches/server/0023-Rail-Optimization-optimized-PoweredRailBlock-logic.patch +++ b/patches/server/0023-Rail-Optimization-optimized-PoweredRailBlock-logic.patch @@ -12,7 +12,7 @@ powered rail logic from a single rail instead of each block iterating separately expensive but also completely unnecessary and with a lot of massive overhead diff --git a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java -index e03125281767845564c48c98c3e6b6bbd269ade1..f65d504227ed9f7abc1236e7c44250a693c8f410 100644 +index e03125281767845564c48c98c3e6b6bbd269ade1..4604ea57707ed51601ea53e32c025112536571de 100644 --- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java +++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java @@ -29,7 +29,7 @@ public class PoweredRailBlock extends BaseRailBlock { @@ -20,41 +20,50 @@ index e03125281767845564c48c98c3e6b6bbd269ade1..f65d504227ed9f7abc1236e7c44250a6 } - protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { -+ public boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { // Leaf - protected -> public ++ public boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) { // Leaf - Rail Optimization - protected -> public if (distance >= world.purpurConfig.railActivationRange) { // Purpur return false; } else { -@@ -117,6 +117,10 @@ public class PoweredRailBlock extends BaseRailBlock { +@@ -117,6 +117,12 @@ public class PoweredRailBlock extends BaseRailBlock { @Override protected void updateState(BlockState state, Level world, BlockPos pos, Block neighbor) { -+ if (org.dreeam.leaf.LeafConfig.optimizedPoweredRails) { ++ // Leaf start - Rail Optimization ++ if (org.dreeam.leaf.config.modules.opt.OptimizedPoweredRails.enabled) { + org.dreeam.leaf.optimize.OptimizedPoweredRails.customUpdateState(this, state, world, pos); + return; + } ++ // Leaf end - Rail Optimization boolean flag = (Boolean) state.getValue(PoweredRailBlock.POWERED); boolean flag1 = world.hasNeighborSignal(pos) || this.findPoweredRailSignal(world, pos, state, true, 0) || this.findPoweredRailSignal(world, pos, state, false, 0); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index e81cb3b303a53b4d2edb80563be806c8ef9c8bed..66cb9f4f2efb3ddc0d38d325fe8c2cb0fa32af08 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -197,6 +197,7 @@ public class LeafConfig { - public static boolean throttleInactiveGoalSelectorTick = true; - public static Map projectileTimeouts; - public static boolean useSpigotItemMergingMechanism = true; -+ public static boolean optimizedPoweredRails = false; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -246,6 +247,7 @@ public class LeafConfig { - entityType.ttl = config.getInt("entity_timeouts." + type, -1); - } - useSpigotItemMergingMechanism = getBoolean("performance.use-spigot-item-merging-mechanism", useSpigotItemMergingMechanism); -+ optimizedPoweredRails = getBoolean("performance.optimizedPoweredRails", optimizedPoweredRails); - } - - private static void network() { +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java b/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a4ce1f3e5ab0d71493cef59154058ebf46db3e4c +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/OptimizedPoweredRails.java +@@ -0,0 +1,21 @@ ++package org.dreeam.leaf.config.modules.opt; ++ ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class OptimizedPoweredRails implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "optimized_powered_rails"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++} diff --git a/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java b/src/main/java/org/dreeam/leaf/optimize/OptimizedPoweredRails.java new file mode 100644 index 0000000000000000000000000000000000000000..9e8bc27585e204aa2df77a90418bbe9e00bcd040 diff --git a/patches/server/0029-Leaves-Jade-Protocol.patch b/patches/server/0029-Leaves-Jade-Protocol.patch index 33aef01e..8d2645f3 100644 --- a/patches/server/0029-Leaves-Jade-Protocol.patch +++ b/patches/server/0029-Leaves-Jade-Protocol.patch @@ -34,23 +34,36 @@ index 7292e68199d244990efa8475fb40b94fe72323c0..3c234bfcecd6d93f8ff9b1abc6dfc72c protected long nextMobSpawnsAt; protected int totalMobsSpawned; protected Optional nextSpawnData; -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index f0c8892e41204caa6ba586e6f99502578ab2c183..12d7ac02f0a7cf1e187a8d381bd92c190c4ba5d9 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -250,7 +250,9 @@ public class LeafConfig { - optimizedPoweredRails = getBoolean("performance.optimizedPoweredRails", optimizedPoweredRails); - } - +diff --git a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b63d87d0593d116b0c5ee835dc4372f1b5542453 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +@@ -0,0 +1,21 @@ ++package org.dreeam.leaf.config.modules.network; ++ ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class ProtocolSupport implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.NETWORK; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "protocol_support"; ++ } ++ ++ @ConfigInfo(baseName = "jade-protocol") + public static boolean jadeProtocol = false; - private static void network() { -+ jadeProtocol = getBoolean("network.protocol.jade-protocol", jadeProtocol); - } - - public static String sentryDsn = ""; ++} diff --git a/src/main/java/top/leavesmc/leaves/protocol/JadeProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/JadeProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..660af969911c0c08619cb5b0eb94ebb8ab2973c8 +index 0000000000000000000000000000000000000000..561a8c33eaf1d961b4d8442bbab8c1ed9eef619c --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/protocol/JadeProtocol.java @@ -0,0 +1,909 @@ @@ -491,14 +504,14 @@ index 0000000000000000000000000000000000000000..660af969911c0c08619cb5b0eb94ebb8 + + @ProtocolHandler.PlayerJoin + public static void onPlayerJoin(ServerPlayer player) { -+ if (org.dreeam.leaf.LeafConfig.jadeProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { + ProtocolUtils.sendPayloadPacket(player, PACKET_SERVER_PING, buf -> buf.writeUtf("{}")); + } + } + + @ProtocolHandler.PayloadReceiver(payload = RequestEntityPayload.class, payloadId = "request_entity") + public static void requestEntityData(ServerPlayer player, RequestEntityPayload payload) { -+ if (!org.dreeam.leaf.LeafConfig.jadeProtocol) { ++ if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { + return; + } + @@ -538,7 +551,7 @@ index 0000000000000000000000000000000000000000..660af969911c0c08619cb5b0eb94ebb8 + + @ProtocolHandler.PayloadReceiver(payload = RequestTilePayload.class, payloadId = "request_tile") + public static void requestTileData(ServerPlayer player, RequestTilePayload payload) { -+ if (!org.dreeam.leaf.LeafConfig.jadeProtocol) { ++ if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { + return; + } + @@ -580,7 +593,7 @@ index 0000000000000000000000000000000000000000..660af969911c0c08619cb5b0eb94ebb8 + + @ProtocolHandler.ReloadServer + public static void onServerReload() { -+ if (org.dreeam.leaf.LeafConfig.jadeProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.jadeProtocol) { + enableAllPlayer(); + } + } diff --git a/patches/server/0030-Leaves-Appleskin-Protocol.patch b/patches/server/0030-Leaves-Appleskin-Protocol.patch index 42df8fb0..ffb8f145 100644 --- a/patches/server/0030-Leaves-Appleskin-Protocol.patch +++ b/patches/server/0030-Leaves-Appleskin-Protocol.patch @@ -6,24 +6,21 @@ Subject: [PATCH] Leaves: Appleskin Protocol Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 71f3e00862daacf7e1c552e5aea66aea2267e29d..db32d6b65c1078ce13dab5fc287711d108de4130 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -251,8 +251,10 @@ public class LeafConfig { - } +diff --git a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +index b63d87d0593d116b0c5ee835dc4372f1b5542453..ef23577faaf7948d7a9b1def4d56506eab19cc80 100644 +--- a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java ++++ b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +@@ -18,4 +18,7 @@ public class ProtocolSupport implements IConfigModule { + @ConfigInfo(baseName = "jade-protocol") public static boolean jadeProtocol = false; ++ ++ @ConfigInfo(baseName = "appleskin-protocol") + public static boolean appleskinProtocol = false; - private static void network() { - jadeProtocol = getBoolean("network.protocol.jade-protocol", jadeProtocol); -+ appleskinProtocol = getBoolean("network.protocol.appleskin-protocol", appleskinProtocol); - } - - public static String sentryDsn = ""; + } diff --git a/src/main/java/top/leavesmc/leaves/protocol/AppleSkinProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/AppleSkinProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..a16cf0afc41e903dda7033bcca6f8cdc9b533390 +index 0000000000000000000000000000000000000000..2e7ad52155b4308a0361c3cdc0ecec97f912ef7f --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/protocol/AppleSkinProtocol.java @@ -0,0 +1,105 @@ @@ -67,14 +64,14 @@ index 0000000000000000000000000000000000000000..a16cf0afc41e903dda7033bcca6f8cdc + + @ProtocolHandler.PlayerJoin + public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { -+ if (org.dreeam.leaf.LeafConfig.appleskinProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { + resetPlayerData(player); + } + } + + @ProtocolHandler.PlayerLeave + public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { -+ if (org.dreeam.leaf.LeafConfig.appleskinProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { + players.remove(player); + resetPlayerData(player); + } @@ -82,14 +79,14 @@ index 0000000000000000000000000000000000000000..a16cf0afc41e903dda7033bcca6f8cdc + + @ProtocolHandler.MinecraftRegister(ignoreId = true) + public static void onPlayerSubscribed(@NotNull ServerPlayer player) { -+ if (org.dreeam.leaf.LeafConfig.appleskinProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { + players.add(player); + } + } + + @ProtocolHandler.Ticker + public static void tick() { -+ if (org.dreeam.leaf.LeafConfig.appleskinProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { + for (ServerPlayer player : players) { + FoodData data = player.getFoodData(); + @@ -116,7 +113,7 @@ index 0000000000000000000000000000000000000000..a16cf0afc41e903dda7033bcca6f8cdc + + @ProtocolHandler.ReloadServer + public static void onServerReload() { -+ if (!org.dreeam.leaf.LeafConfig.appleskinProtocol) { ++ if (!org.dreeam.leaf.config.modules.network.ProtocolSupport.appleskinProtocol) { + disableAllPlayer(); + } + } diff --git a/patches/server/0031-Leaves-Xaero-Map-Protocol.patch b/patches/server/0031-Leaves-Xaero-Map-Protocol.patch index 22560753..8fe7dabf 100644 --- a/patches/server/0031-Leaves-Xaero-Map-Protocol.patch +++ b/patches/server/0031-Leaves-Xaero-Map-Protocol.patch @@ -18,35 +18,32 @@ index 80db3fcf338846770e8c8ee6aa7635a68f2b6753..d9640b2a08101e9bd65323019c1de9c0 if (world.isRaining()) { // CraftBukkit start - handle player weather // entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.START_RAINING, 0.0F)); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index db32d6b65c1078ce13dab5fc287711d108de4130..5b62282f9cb77c17394d51d8b40fecde49daac0c 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -2,6 +2,7 @@ package org.dreeam.leaf; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +index ef23577faaf7948d7a9b1def4d56506eab19cc80..c9736e79387d785a67d6ebe71df6553eeaf2b41d 100644 +--- a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java ++++ b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +@@ -4,6 +4,8 @@ import org.dreeam.leaf.config.ConfigInfo; + import org.dreeam.leaf.config.EnumConfigCategory; + import org.dreeam.leaf.config.IConfigModule; - import com.google.common.collect.ImmutableMap; - import net.minecraft.core.registries.BuiltInRegistries; +import java.util.Random; - import net.minecraft.server.MinecraftServer; - import net.minecraft.world.entity.EntityType; - import org.bukkit.configuration.ConfigurationSection; -@@ -252,9 +253,13 @@ public class LeafConfig { ++ + public class ProtocolSupport implements IConfigModule { - public static boolean jadeProtocol = false; + @Override +@@ -21,4 +23,9 @@ public class ProtocolSupport implements IConfigModule { + + @ConfigInfo(baseName = "appleskin-protocol") public static boolean appleskinProtocol = false; ++ ++ @ConfigInfo(baseName = "xaero-map-protocol") + public static boolean xaeroMapProtocol = false; ++ @ConfigInfo(baseName = "xaero-map-server-id") + public static int xaeroMapServerID = new Random().nextInt(); - private static void network() { - jadeProtocol = getBoolean("network.protocol.jade-protocol", jadeProtocol); - appleskinProtocol = getBoolean("network.protocol.appleskin-protocol", appleskinProtocol); -+ xaeroMapProtocol = getBoolean("network.protocol.xaero-map-protocol", xaeroMapProtocol); -+ xaeroMapServerID = getInt("network.protocol.xaero-map-server-id", xaeroMapServerID); - } - - public static String sentryDsn = ""; + } diff --git a/src/main/java/top/leavesmc/leaves/protocol/XaeroMapProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/XaeroMapProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..6bf670774564bc8c3272d5e08cc7c3530767f8d5 +index 0000000000000000000000000000000000000000..092a91d94aa325dc89f6a84eb885879b70ddc5d3 --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/protocol/XaeroMapProtocol.java @@ -0,0 +1,41 @@ @@ -79,14 +76,14 @@ index 0000000000000000000000000000000000000000..6bf670774564bc8c3272d5e08cc7c353 + } + + public static void onSendWorldInfo(@NotNull ServerPlayer player) { -+ if (org.dreeam.leaf.LeafConfig.xaeroMapProtocol) { ++ if (org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapProtocol) { + ProtocolUtils.sendPayloadPacket(player, MINIMAP_KEY, buf -> { + buf.writeByte(0); -+ buf.writeInt(org.dreeam.leaf.LeafConfig.xaeroMapServerID); ++ buf.writeInt(org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapServerID); + }); + ProtocolUtils.sendPayloadPacket(player, WORLDMAP_KEY, buf -> { + buf.writeByte(0); -+ buf.writeInt(org.dreeam.leaf.LeafConfig.xaeroMapServerID); ++ buf.writeInt(org.dreeam.leaf.config.modules.network.ProtocolSupport.xaeroMapServerID); + }); + } + } diff --git a/patches/server/0032-Leaves-Syncmatica-Protocol.patch b/patches/server/0032-Leaves-Syncmatica-Protocol.patch index ec306ee9..a37ae576 100644 --- a/patches/server/0032-Leaves-Syncmatica-Protocol.patch +++ b/patches/server/0032-Leaves-Syncmatica-Protocol.patch @@ -9,7 +9,7 @@ Original project: https://github.com/LeavesMC/Leaves This patch is Powered by Syncmatica(https://github.com/End-Tech/syncmatica) diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 58fe904de3b3f3b9a823b550a3ad143eac26e8bb..bb0184b33bbb062801f883853350026458c655c7 100644 +index 8895e7d35af8650503853b6fc7432f66e4f333db..451095afa88a2d89d33658042e9a62ef14547cc7 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -310,6 +310,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl @@ -29,31 +29,36 @@ index 58fe904de3b3f3b9a823b550a3ad143eac26e8bb..bb0184b33bbb062801f8838533500264 @Override public void tick() { if (this.ackBlockChangesUpTo > -1) { -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 5b62282f9cb77c17394d51d8b40fecde49daac0c..804b0aa7d9108ce5d7ffff2857e071cba685a168 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -255,11 +255,20 @@ public class LeafConfig { - public static boolean appleskinProtocol = false; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +index c9736e79387d785a67d6ebe71df6553eeaf2b41d..87b5571a5ebd11ea6e64565038b1fac331cfba8e 100644 +--- a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java ++++ b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +@@ -1,5 +1,6 @@ + package org.dreeam.leaf.config.modules.network; + ++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; +@@ -28,4 +29,18 @@ public class ProtocolSupport implements IConfigModule { public static boolean xaeroMapProtocol = false; + @ConfigInfo(baseName = "xaero-map-server-id") public static int xaeroMapServerID = new Random().nextInt(); ++ ++ @ConfigInfo(baseName = "syncmatica-enabled") + public static boolean syncmaticaProtocol = false; ++ @ConfigInfo(baseName = "syncmatica-quota") + public static boolean syncmaticaQuota = false; ++ @ConfigInfo(baseName = "syncmatica-quota-limit") + public static int syncmaticaQuotaLimit = 40000000; - private static void network() { - jadeProtocol = getBoolean("network.protocol.jade-protocol", jadeProtocol); - appleskinProtocol = getBoolean("network.protocol.appleskin-protocol", appleskinProtocol); - xaeroMapProtocol = getBoolean("network.protocol.xaero-map-protocol", xaeroMapProtocol); - xaeroMapServerID = getInt("network.protocol.xaero-map-server-id", xaeroMapServerID); -+ syncmaticaProtocol = getBoolean("network.protocol.syncmatica.enable", syncmaticaProtocol); -+ syncmaticaQuota = getBoolean("network.protocol.syncmatica.quota", syncmaticaQuota); -+ syncmaticaQuotaLimit = getInt("network.protocol.syncmatica.quota-limit", syncmaticaQuotaLimit); ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { + if (syncmaticaProtocol) { + top.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol.init(); + } - } - - public static String sentryDsn = ""; ++ } + } diff --git a/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java new file mode 100644 index 0000000000000000000000000000000000000000..4c2aa74795b0883f280eaa721a83ea6891ffdab2 @@ -1326,7 +1331,7 @@ index 0000000000000000000000000000000000000000..9fbeef1ef528504276895faed4dba41e +} diff --git a/src/main/java/top/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..b36dee2714750f79489cea9fce4855d1cfe3e770 +index 0000000000000000000000000000000000000000..60cec10702a0ea47d2f3181f3046a9fe2b24f5fa --- /dev/null +++ b/src/main/java/top/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java @@ -0,0 +1,122 @@ @@ -1424,7 +1429,7 @@ index 0000000000000000000000000000000000000000..b36dee2714750f79489cea9fce4855d1 + } + + public static boolean isOverQuota(int sent) { -+ return org.dreeam.leaf.LeafConfig.syncmaticaQuota && sent > org.dreeam.leaf.LeafConfig.syncmaticaQuotaLimit; ++ return org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaQuota && sent > org.dreeam.leaf.config.modules.network.ProtocolSupport.syncmaticaQuotaLimit; + } + + public static void backupAndReplace(final Path backup, final Path current, final Path incoming) { diff --git a/patches/server/0033-Leaves-Disable-moved-wrongly-threshold.patch b/patches/server/0033-Leaves-Disable-moved-wrongly-threshold.patch index cf0ab21c..9b0298ed 100644 --- a/patches/server/0033-Leaves-Disable-moved-wrongly-threshold.patch +++ b/patches/server/0033-Leaves-Disable-moved-wrongly-threshold.patch @@ -7,70 +7,75 @@ Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index bb0184b33bbb062801f883853350026458c655c7..bdf9ee08a9661f43b7a568b2aa7e4fc7e44a48c1 100644 +index 451095afa88a2d89d33658042e9a62ef14547cc7..8d4fbf7dd77ef5233936aa5c2bce2e63ecbdebab 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -246,7 +246,6 @@ import org.bukkit.inventory.EquipmentSlot; - import org.bukkit.inventory.InventoryView; - import org.bukkit.inventory.SmithingInventory; - // CraftBukkit end -- - public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener { - - static final Logger LOGGER = LogUtils.getLogger(); -@@ -579,7 +578,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -579,7 +579,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Prevent moving into unloaded chunks - if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { -+ if (!org.dreeam.leaf.LeafConfig.disableMovedWronglyThreshold && d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // Leaves - disable can ++ if (!org.dreeam.leaf.config.modules.gameplay.DisableMovedWronglyThreshold.enabled && d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { // Leaves - disable can // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.send(new ClientboundMoveVehiclePacket(entity)); -@@ -615,7 +614,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -615,7 +615,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; - if (d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot -+ if (!org.dreeam.leaf.LeafConfig.disableMovedWronglyThreshold && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // Leaves - disable can ++ if (!org.dreeam.leaf.config.modules.gameplay.DisableMovedWronglyThreshold.enabled && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot // Leaves - disable can flag2 = true; // Paper - diff on change, this should be moved wrongly ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", new Object[]{entity.getName().getString(), this.player.getName().getString(), Math.sqrt(d10)}); } -@@ -1498,7 +1497,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1498,7 +1498,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, toX, toY, toZ, toYaw, toPitch, true); if (!event.isAllowed()) { - if (event.getLogWarning()) -+ if (!org.dreeam.leaf.LeafConfig.disableMovedWronglyThreshold && event.getLogWarning()) // Leaves - disable can ++ if (!org.dreeam.leaf.config.modules.gameplay.DisableMovedWronglyThreshold.enabled && event.getLogWarning()) // Leaves - disable can ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8}); this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); return; -@@ -1568,7 +1567,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1568,7 +1568,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean movedWrongly = false; // Paper - Add fail move event; rename - if (!this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot -+ if (!org.dreeam.leaf.LeafConfig.disableMovedWronglyThreshold && !this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot // Leaves - disable can ++ if (!org.dreeam.leaf.config.modules.gameplay.DisableMovedWronglyThreshold.enabled && !this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot // Leaves - disable can // Paper start - Add fail move event io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY, toX, toY, toZ, toYaw, toPitch, true); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 804b0aa7d9108ce5d7ffff2857e071cba685a168..c69658ffc6b25c7f54b39830098189ce1585c1b3 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -176,6 +176,7 @@ public class LeafConfig { - public static boolean removeSpigotCheckBungeeConfig = true; - public static boolean removeUseItemOnPacketTooFar = false; - public static double maxUseItemDistance = 1.0000001D; -+ public static boolean disableMovedWronglyThreshold = false; - private static void removal() { - removeMojangUsernameCheck = getBoolean("remove-Mojang-username-check", removeMojangUsernameCheck, - "Remove username check of Mojang", -@@ -186,6 +187,7 @@ public class LeafConfig { - removeUseItemOnPacketTooFar = getBoolean("remove-UseItemOnPacket-too-far-check", removeUseItemOnPacketTooFar, - "To enable this, players can use some packet modules with hack clients and the NoCom Exploit!!"); - maxUseItemDistance = getDouble("max-UseItem-distance", maxUseItemDistance, "The max distance of UseItem for players"); -+ disableMovedWronglyThreshold = getBoolean("disable-MovedWronglyThreshold", disableMovedWronglyThreshold, "Disable moved quickly/wrongly checks"); - } - - public static boolean enableAsyncMobSpawning = true; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/DisableMovedWronglyThreshold.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/DisableMovedWronglyThreshold.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c5afec3c21be35cb69905069a82acfc208a80e92 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/DisableMovedWronglyThreshold.java +@@ -0,0 +1,27 @@ ++package org.dreeam.leaf.config.modules.gameplay; ++ ++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 DisableMovedWronglyThreshold implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.GAMEPLAY; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "disable_moved_wrongly_threshold"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = false; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("gameplay.disable_moved_wrongly_threshold", "Disable moved quickly/wrongly checks"); ++ } ++} diff --git a/patches/server/0034-Leaves-Fix-vehicle-teleport-by-end-gateway.patch b/patches/server/0034-Leaves-Fix-vehicle-teleport-by-end-gateway.patch index 4cbfadef..fa75ef11 100644 --- a/patches/server/0034-Leaves-Fix-vehicle-teleport-by-end-gateway.patch +++ b/patches/server/0034-Leaves-Fix-vehicle-teleport-by-end-gateway.patch @@ -7,7 +7,7 @@ Original license: GPLv3 Original project: https://github.com/LeavesMC/Leaves diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -index 72a69569fab9d62c27c3ea4005c4e24816bdc5cd..82199b522db0fb21e5a74111284f8574f48109c1 100644 +index 72a69569fab9d62c27c3ea4005c4e24816bdc5cd..0c36da54212a7e5ccc2277539daa79e014e0b689 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java @@ -107,7 +107,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity { @@ -15,21 +15,40 @@ index 72a69569fab9d62c27c3ea4005c4e24816bdc5cd..82199b522db0fb21e5a74111284f8574 // Paper start - Ensure safe gateway teleport for (Entity entity : list) { - if (entity.canChangeDimensions()) { -+ if (org.dreeam.leaf.LeafConfig.useVanillaEndTeleport || entity.canChangeDimensions()) { // Leaf - be vanilla ++ if (org.dreeam.leaf.config.modules.gameplay.UseVanillaEndTeleport.enabled || entity.canChangeDimensions()) { // Leaf - be vanilla TheEndGatewayBlockEntity.teleportEntity(world, pos, state, entity, blockEntity); break; } -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index c69658ffc6b25c7f54b39830098189ce1585c1b3..9fe0574ca955e331752a0a324e4582dc5c178f89 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -282,4 +282,9 @@ public class LeafConfig { - gg.pufferfish.pufferfish.sentry.SentryManager.init(); - } - } +diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/UseVanillaEndTeleport.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/UseVanillaEndTeleport.java +new file mode 100644 +index 0000000000000000000000000000000000000000..778f428eaaf22236e52aa4b670f5ec34996ea862 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/UseVanillaEndTeleport.java +@@ -0,0 +1,27 @@ ++package org.dreeam.leaf.config.modules.gameplay; + -+ public static boolean useVanillaEndTeleport = false; -+ private static void vanillaEndTeleport() { -+ useVanillaEndTeleport = getBoolean("use-vanilla-end-teleport", useVanillaEndTeleport, "Vanilla End Gateway Teleport"); ++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 UseVanillaEndTeleport implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.GAMEPLAY; + } - } ++ ++ @Override ++ public String getBaseName() { ++ return "use_vanilla_end_teleport"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = false; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("gameplay.use_vanilla_end_teleport", "Enable to Use Vanilla End Gateway Teleport"); ++ } ++} diff --git a/patches/server/0038-Petal-Async-Pathfinding.patch b/patches/server/0038-Petal-Async-Pathfinding.patch index 4cc919af..9f5d4d62 100644 --- a/patches/server/0038-Petal-Async-Pathfinding.patch +++ b/patches/server/0038-Petal-Async-Pathfinding.patch @@ -15,7 +15,7 @@ This patch was ported downstream from the Petal fork. Makes most pathfinding-related work happen asynchronously diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 69c0b1c756b5e18eefd825421662f2ae237e164e..a957011f62db2400e503c5313e96e1ef67bcfc60 100644 +index b0f151360a6263192aed9c1ff79c442bfe488483..6e3617696c50262574dfba2048f18edd1f7d88ef 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -294,6 +294,7 @@ public abstract class Mob extends LivingEntity implements Targeting { @@ -27,7 +27,7 @@ index 69c0b1c756b5e18eefd825421662f2ae237e164e..a957011f62db2400e503c5313e96e1ef } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java -index aed7e9affaae1e0d1e3324a41e5818435f76fd0f..88df3d26eae35a7bc543eff4f6e054100eaca879 100644 +index aed7e9affaae1e0d1e3324a41e5818435f76fd0f..84b5552436b22ecfd2b88c6609ce8e583632cda7 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java @@ -7,7 +7,6 @@ import java.util.HashSet; @@ -51,7 +51,7 @@ index aed7e9affaae1e0d1e3324a41e5818435f76fd0f..88df3d26eae35a7bc543eff4f6e05410 Set, BlockPos>> set = new java.util.HashSet<>(poiposes); // Paper end - optimise POI access + // Kaiiju start - petal - Async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) { ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + // await on path async + Path possiblePath = findPathToPois(entity, set); + @@ -96,7 +96,7 @@ index aed7e9affaae1e0d1e3324a41e5818435f76fd0f..88df3d26eae35a7bc543eff4f6e05410 return true; } diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java -index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..16809bd3e914b19dddb5985d3468808cd0f90d91 100644 +index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..e37ecae581e3723e36808fe51bcee9034b69b803 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java @@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior { @@ -112,10 +112,10 @@ index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..16809bd3e914b19dddb5985d3468808c WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); boolean bl = this.reachedTarget(entity, walkTarget); - if (!bl && this.tryComputePath(entity, walkTarget, world.getGameTime())) { -+ if (!org.dreeam.leaf.LeafConfig.asyncPathfinding && !bl && this.tryComputePath(entity, walkTarget, world.getGameTime())) { // Kaiiju - petal - async path processing means we can't know if the path is reachable here ++ if (!org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled && !bl && this.tryComputePath(entity, walkTarget, world.getGameTime())) { // Kaiiju - petal - async path processing means we can't know if the path is reachable here this.lastTargetPos = walkTarget.getTarget().currentBlockPosition(); return true; -+ } else if (org.dreeam.leaf.LeafConfig.asyncPathfinding && !bl) { return true; // Kaiiju - async pathfinding ++ } else if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled && !bl) { return true; // Kaiiju - async pathfinding } else { brain.eraseMemory(MemoryModuleType.WALK_TARGET); if (bl) { @@ -123,7 +123,7 @@ index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..16809bd3e914b19dddb5985d3468808c @Override protected boolean canStillUse(ServerLevel world, Mob entity, long time) { -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding && !this.finishedProcessing) return true; // Kaiiju - petal - wait for processing ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled && !this.finishedProcessing) return true; // Kaiiju - petal - wait for processing if (this.path != null && this.lastTargetPos != null) { Optional optional = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET); boolean bl = optional.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false); @@ -132,7 +132,7 @@ index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..16809bd3e914b19dddb5985d3468808c @Override protected void start(ServerLevel serverLevel, Mob mob, long l) { + // Kaiiju start - petal - start processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) { ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + Brain brain = mob.getBrain(); + WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); + @@ -149,7 +149,7 @@ index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..16809bd3e914b19dddb5985d3468808c @Override protected void tick(ServerLevel serverLevel, Mob mob, long l) { + // Kaiiju start - petal - Async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) { ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + if (this.path != null && !this.path.isProcessed()) return; // wait for processing + + if (!this.finishedProcessing) { @@ -221,7 +221,7 @@ index 1ab77f3518d1df30f66ae44d7d4fa69e5b32d93a..16809bd3e914b19dddb5985d3468808c private boolean tryComputePath(Mob entity, WalkTarget walkTarget, long time) { BlockPos blockPos = walkTarget.getTarget().currentBlockPosition(); diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java -index 271efbb027f6f5d69ac5bc5dc51102a1eb00ab31..803125d32fcbada7b347868b547b0ec96984810f 100644 +index 271efbb027f6f5d69ac5bc5dc51102a1eb00ab31..08aa5cef303924c537f83b431b275853e652b5ba 100644 --- a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java @@ -20,6 +20,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiTypes; @@ -237,7 +237,7 @@ index 271efbb027f6f5d69ac5bc5dc51102a1eb00ab31..803125d32fcbada7b347868b547b0ec9 return poiType.is(PoiTypes.HOME); }, predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY).collect(Collectors.toSet()); + // Kaiiju start - petal - Async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) { ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + // await on path async + Path possiblePath = AcquirePoi.findPathToPois(entity, set); + @@ -281,7 +281,7 @@ index 6771f2dc974317b6b152288bf41d1a95bc78a8e4..7a641747b17164b09bb8483cda7f69d1 Node node = path.getNode(i); this.doorPos = new BlockPos(node.x, node.y + 1, node.z); diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java -index 9d3b32c852d660356e0f16d4cc10072b1c603e64..b79bf10b6646d32adee342ba4ddc48af4395836e 100644 +index 9d3b32c852d660356e0f16d4cc10072b1c603e64..fa843dd6fb4af72ab212d1d3d8440649240dc162 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java @@ -6,16 +6,34 @@ import net.minecraft.world.level.Level; @@ -312,7 +312,7 @@ index 9d3b32c852d660356e0f16d4cc10072b1c603e64..b79bf10b6646d32adee342ba4ddc48af this.nodeEvaluator = new AmphibiousNodeEvaluator(false); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + else + // Kaiiju end @@ -320,7 +320,7 @@ index 9d3b32c852d660356e0f16d4cc10072b1c603e64..b79bf10b6646d32adee342ba4ddc48af } diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java -index e35c38feb62c3345d82636081decc09db9f061ab..81407641098f287095b603699f6dcb7d38475f01 100644 +index e35c38feb62c3345d82636081decc09db9f061ab..7c5a9cbff031c0f78c50f3e31c0cea661e3c83aa 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java @@ -10,16 +10,34 @@ import net.minecraft.world.level.pathfinder.FlyNodeEvaluator; @@ -351,7 +351,7 @@ index e35c38feb62c3345d82636081decc09db9f061ab..81407641098f287095b603699f6dcb7d this.nodeEvaluator = new FlyNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + else + // Kaiiju end @@ -367,7 +367,7 @@ index e35c38feb62c3345d82636081decc09db9f061ab..81407641098f287095b603699f6dcb7d if (!this.isDone()) { if (this.canUpdatePath()) { diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java -index 47de460ff5435ea6712c800c77093126908d0fce..c9f59d43872c1bd2de8330ea4ad84794cc2f1a2a 100644 +index 47de460ff5435ea6712c800c77093126908d0fce..278f05d3d27d32e94e049f50d63965a3351619fe 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java @@ -15,6 +15,8 @@ import net.minecraft.world.level.pathfinder.Path; @@ -399,7 +399,7 @@ index 47de460ff5435ea6712c800c77093126908d0fce..c9f59d43872c1bd2de8330ea4ad84794 this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + else + // Kaiiju end @@ -407,7 +407,7 @@ index 47de460ff5435ea6712c800c77093126908d0fce..c9f59d43872c1bd2de8330ea4ad84794 } diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java -index 33983ed67ad6b0d25d2ae00e03415bda940584eb..6e53bf2a5fe0f407d3d71a6f485d3b327eb8cec3 100644 +index 33983ed67ad6b0d25d2ae00e03415bda940584eb..89b97f322ba32b24e87d850143f4434a7e00699a 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java @@ -25,6 +25,8 @@ import net.minecraft.world.level.pathfinder.PathFinder; @@ -435,7 +435,7 @@ index 33983ed67ad6b0d25d2ae00e03415bda940584eb..6e53bf2a5fe0f407d3d71a6f485d3b32 PathNavigationRegion pathNavigationRegion = new PathNavigationRegion(this.level, blockPos.offset(-i, -i, -i), blockPos.offset(i, i, i)); Path path = this.pathFinder.findPath(pathNavigationRegion, this.mob, positions, followRange, distance, this.maxVisitedNodesMultiplier); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) { ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + // assign early a target position. most calls will only have 1 position + if (!positions.isEmpty()) this.targetPos = positions.iterator().next(); + @@ -497,7 +497,7 @@ index 33983ed67ad6b0d25d2ae00e03415bda940584eb..6e53bf2a5fe0f407d3d71a6f485d3b32 Vec3 vec3 = new Vec3(((double)node.x + this.mob.getX()) / 2.0D, ((double)node.y + this.mob.getY()) / 2.0D, ((double)node.z + this.mob.getZ()) / 2.0D); return pos.closerToCenterThan(vec3, (double)(this.path.getNodeCount() - this.path.getNextNodeIndex())); diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java -index ee8543afbbd681bf327a353530a7a635aa5ef592..fc536c1c2edebff49e29b626ec1552a42cabca5e 100644 +index ee8543afbbd681bf327a353530a7a635aa5ef592..8442ca52fe7fff47c3cc24ebb6d40e4f40bb85f3 100644 --- a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java @@ -7,6 +7,8 @@ import net.minecraft.world.level.Level; @@ -529,7 +529,7 @@ index ee8543afbbd681bf327a353530a7a635aa5ef592..fc536c1c2edebff49e29b626ec1552a4 this.allowBreaching = this.mob.getType() == EntityType.DOLPHIN; this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching); + // Kaiiju start - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + else + // Kaiiju end @@ -537,7 +537,7 @@ index ee8543afbbd681bf327a353530a7a635aa5ef592..fc536c1c2edebff49e29b626ec1552a4 } diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java -index 8db20db72cd51046213625fac46c35854c59ec5d..23d5402a4093890daacdafe3411457c1f73daffe 100644 +index 8db20db72cd51046213625fac46c35854c59ec5d..dbe9d592aa8b7c64ed375cfb8d135c6f84e0bd75 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java @@ -7,7 +7,7 @@ import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; @@ -562,7 +562,7 @@ index 8db20db72cd51046213625fac46c35854c59ec5d..23d5402a4093890daacdafe3411457c1 // don't ask me why it's unbounded. ask mojang. io.papermc.paper.util.PoiAccess.findAnyPoiPositions(poiManager, type -> type.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY, false, Integer.MAX_VALUE, poiposes); + // Kaiiju start - await on async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) { ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) { + Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); + AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + // read canReach check @@ -614,7 +614,7 @@ index 997ab942be9f742804041b07d607e7dd6473ba96..9ef7be84999ab0ec39d2b58a48cdaebf } } diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java -index 819445535895fbf79b99222bc6bf33cbd9089813..27fd37b650698cb73b93f84d536043ca1f7875d4 100644 +index 819445535895fbf79b99222bc6bf33cbd9089813..2957a7617acae18e23d8ffb90ed5c790681da9c1 100644 --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java @@ -41,7 +41,6 @@ import net.minecraft.world.entity.VariantHolder; @@ -657,7 +657,7 @@ index 819445535895fbf79b99222bc6bf33cbd9089813..27fd37b650698cb73b93f84d536043ca this.nodeEvaluator = new Frog.FrogNodeEvaluator(true); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + else + // Kaiiju end @@ -686,7 +686,7 @@ index 7600e747d91ae888eb801cfafcb09bffb76c8e62..0939ca7c225790c7a294accd820be3ff if (blockposition != null) { diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java -index 2f49b528601a1feb7246fe7a9b83ce828c2d78fc..b5bde65dea5435ac559c0aca92d19aa87c255b05 100644 +index 2f49b528601a1feb7246fe7a9b83ce828c2d78fc..42f6f629219771f45597cc8a0802fa1ed44d0344 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Strider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java @@ -74,6 +74,8 @@ import net.minecraft.world.phys.AABB; @@ -718,7 +718,7 @@ index 2f49b528601a1feb7246fe7a9b83ce828c2d78fc..b5bde65dea5435ac559c0aca92d19aa8 this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + else + // Kaiiju end @@ -726,7 +726,7 @@ index 2f49b528601a1feb7246fe7a9b83ce828c2d78fc..b5bde65dea5435ac559c0aca92d19aa8 } diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java -index 07fa613d75f3659145945245926e9068057e3ed2..da834424b655d49388926a0472cacb5ecc4d56fd 100644 +index 07fa613d75f3659145945245926e9068057e3ed2..df0d0868c11c26b2cadc1a07196a0191e16838a0 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java @@ -623,6 +623,16 @@ public class Warden extends Monster implements VibrationSystem { @@ -734,7 +734,7 @@ index 07fa613d75f3659145945245926e9068057e3ed2..da834424b655d49388926a0472cacb5e this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator.setCanPassDoors(true); + // Kaiiju start - petal - async path processing -+ if (org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + return new PathFinder(this.nodeEvaluator, range, GroundPathNavigation.nodeEvaluatorGenerator) { + @Override + protected float distance(Node a, Node b) { @@ -795,7 +795,7 @@ index 3049edb5a8b5967e5242a3896b23665888eb3472..0da9acd785cf785d82be7aab0a1e2bfd return false; } else if (o.nodes.size() != this.nodes.size()) { diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java -index 61d5fe8e5344a6cb94d427859488c34821c8a3f6..6c16cace2e0994516fda29981a8e3482f8de8c2c 100644 +index 61d5fe8e5344a6cb94d427859488c34821c8a3f6..ae9e47036c5de04383ea798f6c3899686f2243cb 100644 --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java @@ -1,20 +1,18 @@ @@ -847,7 +847,7 @@ index 61d5fe8e5344a6cb94d427859488c34821c8a3f6..6c16cace2e0994516fda29981a8e3482 - this.openSet.clear(); - this.nodeEvaluator.prepare(world, mob); - Node node = this.nodeEvaluator.getStart(); -+ if (!org.dreeam.leaf.LeafConfig.asyncPathfinding) ++ if (!org.dreeam.leaf.config.modules.async.AsyncPathfinding.enabled) + this.openSet.clear(); // Kaiiju - petal - it's always cleared in processPath + // Kaiiju start - petal - use a generated evaluator if we have one otherwise run sync + NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null @@ -942,38 +942,6 @@ index 0e2b14e7dfedf209d63279c81723fd7955122d78..079b278e2e262af433bb5bd0c12b3d8d private final Long2ObjectMap pathTypesByPosCache = new Long2ObjectOpenHashMap<>(); public SwimNodeEvaluator(boolean canJumpOutOfWater) { -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 9be596251deb2c73e8af7f4e62a3a24c72cc0369..abcf4fee07b6ea85de116252b823d30e57006654 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -201,6 +201,9 @@ public class LeafConfig { - public static Map projectileTimeouts; - public static boolean useSpigotItemMergingMechanism = true; - public static boolean optimizedPoweredRails = false; -+ public static boolean asyncPathfinding = false; -+ public static int asyncPathfindingMaxThreads = 0; -+ public static int asyncPathfindingKeepalive = 60; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -251,6 +254,17 @@ public class LeafConfig { - } - useSpigotItemMergingMechanism = getBoolean("performance.use-spigot-item-merging-mechanism", useSpigotItemMergingMechanism); - optimizedPoweredRails = getBoolean("performance.optimizedPoweredRails", optimizedPoweredRails); -+ asyncPathfinding = getBoolean("performance.async-pathfinding.enable", asyncPathfinding); -+ asyncPathfindingMaxThreads = getInt("performance.async-pathfinding.max-threads", asyncPathfindingMaxThreads); -+ asyncPathfindingKeepalive = getInt("performance.async-pathfinding.keepalive", asyncPathfindingKeepalive); -+ if (asyncPathfindingMaxThreads < 0) -+ asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncPathfindingMaxThreads, 1); -+ else if (asyncPathfindingMaxThreads == 0) -+ asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1); -+ if (!asyncPathfinding) -+ asyncPathfindingMaxThreads = 0; -+ else -+ MinecraftServer.LOGGER.info("Using {} threads for Async Pathfinding", asyncPathfindingMaxThreads); - } - - public static boolean jadeProtocol = false; diff --git a/src/main/java/org/dreeam/leaf/async/path/AsyncPath.java b/src/main/java/org/dreeam/leaf/async/path/AsyncPath.java new file mode 100644 index 0000000000000000000000000000000000000000..2f5aff1f0e2aca0a8bfeab27c4ab027ffc21055d @@ -1269,7 +1237,7 @@ index 0000000000000000000000000000000000000000..2f5aff1f0e2aca0a8bfeab27c4ab027f +} diff --git a/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java b/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java new file mode 100644 -index 0000000000000000000000000000000000000000..5f3cc1ebc1c3d3293b04e763eff9540c716bc52e +index 0000000000000000000000000000000000000000..8f6b482f94bc646b679e644cf10821ade1a69773 --- /dev/null +++ b/src/main/java/org/dreeam/leaf/async/path/AsyncPathProcessor.java @@ -0,0 +1,52 @@ @@ -1293,8 +1261,8 @@ index 0000000000000000000000000000000000000000..5f3cc1ebc1c3d3293b04e763eff9540c + + private static final Executor pathProcessingExecutor = new ThreadPoolExecutor( + 1, -+ org.dreeam.leaf.LeafConfig.asyncPathfindingMaxThreads, -+ org.dreeam.leaf.LeafConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS, ++ org.dreeam.leaf.config.modules.async.AsyncPathfinding.asyncPathfindingMaxThreads, ++ org.dreeam.leaf.config.modules.async.AsyncPathfinding.asyncPathfindingKeepalive, TimeUnit.SECONDS, + new LinkedBlockingQueue<>(), + new ThreadFactoryBuilder() + .setNameFormat("petal-async-path-thread-%d") @@ -1444,3 +1412,48 @@ index 0000000000000000000000000000000000000000..c0527323c42acf7e4728237e268f075e + return WALK; + } +} +diff --git a/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java b/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java +new file mode 100644 +index 0000000000000000000000000000000000000000..66f28420272997d685b95c57eeee4fb70829adbb +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/async/AsyncPathfinding.java +@@ -0,0 +1,39 @@ ++package org.dreeam.leaf.config.modules.async; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import net.minecraft.server.MinecraftServer; ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class AsyncPathfinding implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.ASYNC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "async_pathfinding"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = false; ++ @ConfigInfo(baseName = "max-threads") ++ public static int asyncPathfindingMaxThreads = 0; ++ @ConfigInfo(baseName = "keepalive") ++ public static int asyncPathfindingKeepalive = 60; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ if (asyncPathfindingMaxThreads < 0) ++ asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncPathfindingMaxThreads, 1); ++ else if (asyncPathfindingMaxThreads == 0) ++ asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1); ++ if (!enabled) ++ asyncPathfindingMaxThreads = 0; ++ else ++ MinecraftServer.LOGGER.info("Using {} threads for Async Pathfinding", asyncPathfindingMaxThreads); ++ } ++} diff --git a/patches/server/0039-Petal-Multithreaded-Tracker.patch b/patches/server/0039-Petal-Multithreaded-Tracker.patch index ef2f4940..48963af2 100644 --- a/patches/server/0039-Petal-Multithreaded-Tracker.patch +++ b/patches/server/0039-Petal-Multithreaded-Tracker.patch @@ -24,7 +24,7 @@ Some things are too unsafe to run off the main thread so we don't attempt to do that. This multithreaded tracker remains accurate, non-breaking and fast. diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -index 06dfd0b27ac0006a2be07f54a0702519a691c6ec..daacdb976ba717bc1137b3c78ecd5dd8968d12af 100644 +index 06dfd0b27ac0006a2be07f54a0702519a691c6ec..cc38235d2b5f3fc5113a4d495f14f81cd24d7cb9 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java @@ -3,6 +3,7 @@ package io.papermc.paper.plugin.manager; @@ -41,7 +41,7 @@ index 06dfd0b27ac0006a2be07f54a0702519a691c6ec..daacdb976ba717bc1137b3c78ecd5dd8 } else if (!isAsync && !onPrimaryThread && !this.server.isStopping()) { - throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); + // Leaf start - petal -+ if (org.dreeam.leaf.LeafConfig.asyncEntityTracker) { ++ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) { + MinecraftServer.getServer().scheduleOnMain(event::callEvent); + return; + } else { @@ -78,7 +78,7 @@ index 66721a27cc9a373a12dffb72c4a403473377eff6..2fbab1b4d20c3ead0ed1a117b29679fa public FullChunkStatus status; diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index 2b9968a8a3d0d66d9db5a83dcf2a44767a9fe412..9050b1c2c77acd335da0ec404ce1322621ba3025 100644 +index 2b9968a8a3d0d66d9db5a83dcf2a44767a9fe412..e95f6053982f9637c195243ceab37061b31355b5 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1128,8 +1128,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -100,7 +100,7 @@ index 2b9968a8a3d0d66d9db5a83dcf2a44767a9fe412..9050b1c2c77acd335da0ec404ce13226 + // Paper start - optimised tracker private final void processTrackQueue() { -+ if (org.dreeam.leaf.LeafConfig.asyncEntityTracker) { ++ if (org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled) { + if (this.multithreadedTracker == null) { + this.multithreadedTracker = new org.dreeam.leaf.async.tracker.MultithreadedTracker(this.level.chunkSource.entityTickingChunks, this.trackerMainThreadTasks); + } @@ -274,43 +274,9 @@ index a3b9068efc38b3eb05e884bcc3fb13532e49308d..f016b5e323f8167d058f614800957216 return this.entityLookup; // Paper - rewrite chunk system } -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index abcf4fee07b6ea85de116252b823d30e57006654..af11b77112752a8bb64f6a5cac265a2d2eebf971 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -204,6 +204,9 @@ public class LeafConfig { - public static boolean asyncPathfinding = false; - public static int asyncPathfindingMaxThreads = 0; - public static int asyncPathfindingKeepalive = 60; -+ public static boolean asyncEntityTracker = false; -+ public static int asyncEntityTrackerMaxThreads = 0; -+ public static int asyncEntityTrackerKeepalive = 60; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -265,6 +268,19 @@ public class LeafConfig { - asyncPathfindingMaxThreads = 0; - else - MinecraftServer.LOGGER.info("Using {} threads for Async Pathfinding", asyncPathfindingMaxThreads); -+ asyncEntityTracker = getBoolean("performance.async-entity-tracker.enable", asyncEntityTracker, -+ "Whether or not async entity tracking should be enabled.", -+ "You may encounter issues with NPCs"); -+ asyncEntityTrackerMaxThreads = getInt("performance.async-entity-tracker.max-threads", asyncEntityTrackerMaxThreads); -+ asyncEntityTrackerKeepalive = getInt("performance.async-entity-tracker.keepalive", asyncEntityTrackerKeepalive); -+ if (asyncEntityTrackerMaxThreads < 0) -+ asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1); -+ else if (asyncEntityTrackerMaxThreads == 0) -+ asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1); -+ if (!asyncEntityTracker) -+ asyncEntityTrackerMaxThreads = 0; -+ else -+ MinecraftServer.LOGGER.info("Using {} threads for Async Entity Tracker", asyncEntityTrackerMaxThreads); - } - - public static boolean jadeProtocol = false; diff --git a/src/main/java/org/dreeam/leaf/async/tracker/MultithreadedTracker.java b/src/main/java/org/dreeam/leaf/async/tracker/MultithreadedTracker.java new file mode 100644 -index 0000000000000000000000000000000000000000..a19a664eb91e28486baf5699e9dc1321be13ec5c +index 0000000000000000000000000000000000000000..83bd78db3affa7bd7ac646f6b56ec2563051fdc3 --- /dev/null +++ b/src/main/java/org/dreeam/leaf/async/tracker/MultithreadedTracker.java @@ -0,0 +1,156 @@ @@ -340,8 +306,8 @@ index 0000000000000000000000000000000000000000..a19a664eb91e28486baf5699e9dc1321 + + private static final Executor trackerExecutor = new ThreadPoolExecutor( + 1, -+ org.dreeam.leaf.LeafConfig.asyncPathfindingMaxThreads, -+ org.dreeam.leaf.LeafConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS, ++ org.dreeam.leaf.config.modules.async.MultithreadedTracker.asyncEntityTrackerMaxThreads, ++ org.dreeam.leaf.config.modules.async.MultithreadedTracker.asyncEntityTrackerKeepalive, TimeUnit.SECONDS, + new LinkedBlockingQueue<>(), + new ThreadFactoryBuilder() + .setNameFormat("petal-async-tracker-thread-%d") @@ -371,7 +337,7 @@ index 0000000000000000000000000000000000000000..a19a664eb91e28486baf5699e9dc1321 + this.taskIndex.set(iterator); + this.finishedTasks.set(0); + -+ for (int i = 0; i < org.dreeam.leaf.LeafConfig.asyncPathfindingMaxThreads; i++) { ++ for (int i = 0; i < org.dreeam.leaf.config.modules.async.MultithreadedTracker.asyncEntityTrackerMaxThreads; i++) { + trackerExecutor.execute(this::runUpdatePlayers); + } + @@ -380,7 +346,7 @@ index 0000000000000000000000000000000000000000..a19a664eb91e28486baf5699e9dc1321 + this.handleChunkUpdates(5); // assist + } + -+ while (this.finishedTasks.get() != org.dreeam.leaf.LeafConfig.asyncPathfindingMaxThreads) { ++ while (this.finishedTasks.get() != org.dreeam.leaf.config.modules.async.MultithreadedTracker.asyncEntityTrackerMaxThreads) { + this.runMainThreadTasks(); + } + @@ -471,3 +437,52 @@ index 0000000000000000000000000000000000000000..a19a664eb91e28486baf5699e9dc1321 + +} \ No newline at end of file +diff --git a/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java b/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a08da88d257ac8b87b1587c2d01355a443385f58 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/async/MultithreadedTracker.java +@@ -0,0 +1,43 @@ ++package org.dreeam.leaf.config.modules.async; ++ ++import com.electronwill.nightconfig.core.file.CommentedFileConfig; ++import net.minecraft.server.MinecraftServer; ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class MultithreadedTracker implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.ASYNC; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "async_entity_tracker"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = false; ++ @ConfigInfo(baseName = "max-threads") ++ public static int asyncEntityTrackerMaxThreads = 0; ++ @ConfigInfo(baseName = "keepalive") ++ public static int asyncEntityTrackerKeepalive = 60; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("", """ ++ Whether or not async entity tracking should be enabled. ++ You may encounter issues with NPCs"""); ++ ++ if (asyncEntityTrackerMaxThreads < 0) ++ asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1); ++ else if (asyncEntityTrackerMaxThreads == 0) ++ asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() / 4, 1); ++ if (!enabled) ++ asyncEntityTrackerMaxThreads = 0; ++ else ++ MinecraftServer.LOGGER.info("Using {} threads for Async Entity Tracker", asyncEntityTrackerMaxThreads); ++ } ++} diff --git a/patches/server/0042-Cache-minecart-vehicle-collision-results.patch b/patches/server/0042-Cache-minecart-vehicle-collision-results.patch index 149d0166..dc6ab74f 100644 --- a/patches/server/0042-Cache-minecart-vehicle-collision-results.patch +++ b/patches/server/0042-Cache-minecart-vehicle-collision-results.patch @@ -9,7 +9,7 @@ Cache minecart vehicle collision results to prevent lag causing by massive stack The known issue: entity can't enter the minecart after enabling this! diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java -index eb5bd5cfd131042e366872bf599a315d83dc732b..ce07e75c4faf30520c74016c4ff31be1cc1c9af7 100644 +index eb5bd5cfd131042e366872bf599a315d83dc732b..024000e5b1c36e72a4b6cfff233d7a64cdb80758 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java @@ -5,6 +5,8 @@ import com.google.common.collect.ImmutableMap; @@ -43,8 +43,8 @@ index eb5bd5cfd131042e366872bf599a315d83dc732b..ce07e75c4faf30520c74016c4ff31be1 if (this.getMinecartType() == AbstractMinecart.Type.RIDEABLE && this.getDeltaMovement().horizontalDistanceSqr() > 0.01D) { - List list = this.level().getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D), EntitySelector.pushableBy(this)); + // Leaf start - Cache minecart vehicle collision results -+ if (org.dreeam.leaf.LeafConfig.cacheMinecartCollision) this.checkAndUpdateCache(true); -+ List list = org.dreeam.leaf.LeafConfig.cacheMinecartCollision ? this.lastCollideCache : this.level().getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D), EntitySelector.pushableBy(this));; // Leaf - Cache minecart vehicle collision results ++ if (org.dreeam.leaf.config.modules.opt.CacheMinecartCollision.enabled) this.checkAndUpdateCache(true); ++ List list = org.dreeam.leaf.config.modules.opt.CacheMinecartCollision.enabled ? this.lastCollideCache : this.level().getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D), EntitySelector.pushableBy(this));; // Leaf - Cache minecart vehicle collision results if (!list.isEmpty()) { - Iterator iterator = list.iterator(); @@ -64,8 +64,8 @@ index eb5bd5cfd131042e366872bf599a315d83dc732b..ce07e75c4faf30520c74016c4ff31be1 - - while (iterator1.hasNext()) { - Entity entity1 = (Entity) iterator1.next(); -+ if (org.dreeam.leaf.LeafConfig.cacheMinecartCollision) this.checkAndUpdateCache(false); // Leaf - Cache minecart vehicle collision results -+ List list2 = org.dreeam.leaf.LeafConfig.cacheMinecartCollision ? this.lastCollideCache : this.level().getEntities(this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D));; // Leaf - Cache minecart vehicle collision results ++ if (org.dreeam.leaf.config.modules.opt.CacheMinecartCollision.enabled) this.checkAndUpdateCache(false); // Leaf - Cache minecart vehicle collision results ++ List list2 = org.dreeam.leaf.config.modules.opt.CacheMinecartCollision.enabled ? this.lastCollideCache : this.level().getEntities(this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D));; // Leaf - Cache minecart vehicle collision results + for (Entity entity1 : list2) { if (!this.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof AbstractMinecart) { @@ -79,24 +79,37 @@ index eb5bd5cfd131042e366872bf599a315d83dc732b..ce07e75c4faf30520c74016c4ff31be1 this.updateInWaterStateAndDoFluidPushing(); if (this.isInLava()) { -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index af11b77112752a8bb64f6a5cac265a2d2eebf971..c73a2f9c3286ecdf57d6cab5c130f69540741a56 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -207,6 +207,7 @@ public class LeafConfig { - public static boolean asyncEntityTracker = false; - public static int asyncEntityTrackerMaxThreads = 0; - public static int asyncEntityTrackerKeepalive = 60; -+ public static boolean cacheMinecartCollision = false; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -281,6 +282,8 @@ public class LeafConfig { - asyncEntityTrackerMaxThreads = 0; - else - MinecraftServer.LOGGER.info("Using {} threads for Async Entity Tracker", asyncEntityTrackerMaxThreads); -+ cacheMinecartCollision = getBoolean("performance.cache-minecart-collision", cacheMinecartCollision, -+ "Cache the minecart collision result to prevent massive stacked minecart lag the server."); - } - - public static boolean jadeProtocol = false; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/CacheMinecartCollision.java b/src/main/java/org/dreeam/leaf/config/modules/opt/CacheMinecartCollision.java +new file mode 100644 +index 0000000000000000000000000000000000000000..edd7f1440751f535a209a6762c152532f2bb0427 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/CacheMinecartCollision.java +@@ -0,0 +1,28 @@ ++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 CacheMinecartCollision implements IConfigModule { ++ ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "cache_minecart_collision"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = false; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("performance.cache_minecart_collision", "Cache the minecart collision result to prevent massive stacked minecart lag the server."); ++ } ++} diff --git a/patches/server/0045-Faster-Random-for-xaeroMapServerID-generation.patch b/patches/server/0045-Faster-Random-for-xaeroMapServerID-generation.patch index f375d139..e7b24c42 100644 --- a/patches/server/0045-Faster-Random-for-xaeroMapServerID-generation.patch +++ b/patches/server/0045-Faster-Random-for-xaeroMapServerID-generation.patch @@ -4,25 +4,25 @@ Date: Mon, 9 Oct 2023 21:33:08 -0400 Subject: [PATCH] Faster Random for xaeroMapServerID generation -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index c73a2f9c3286ecdf57d6cab5c130f69540741a56..2b9e07b9e6e4f4d4e8b3e52192a983c2ad59abbf 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -2,7 +2,7 @@ package org.dreeam.leaf; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +index 87b5571a5ebd11ea6e64565038b1fac331cfba8e..3e5e27efac1791cce961ec144405d8215ab87996 100644 +--- a/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java ++++ b/src/main/java/org/dreeam/leaf/config/modules/network/ProtocolSupport.java +@@ -5,7 +5,7 @@ import org.dreeam.leaf.config.ConfigInfo; + import org.dreeam.leaf.config.EnumConfigCategory; + import org.dreeam.leaf.config.IConfigModule; - import com.google.common.collect.ImmutableMap; - import net.minecraft.core.registries.BuiltInRegistries; -import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; - import net.minecraft.server.MinecraftServer; - import net.minecraft.world.entity.EntityType; - import org.bukkit.configuration.ConfigurationSection; -@@ -289,7 +289,7 @@ public class LeafConfig { - public static boolean jadeProtocol = false; - public static boolean appleskinProtocol = false; + + public class ProtocolSupport implements IConfigModule { + +@@ -28,7 +28,7 @@ public class ProtocolSupport implements IConfigModule { + @ConfigInfo(baseName = "xaero-map-protocol") public static boolean xaeroMapProtocol = false; + @ConfigInfo(baseName = "xaero-map-server-id") - public static int xaeroMapServerID = new Random().nextInt(); + public static int xaeroMapServerID = ThreadLocalRandom.current().nextInt(); // Leaf - Faster Random + + @ConfigInfo(baseName = "syncmatica-enabled") public static boolean syncmaticaProtocol = false; - public static boolean syncmaticaQuota = false; - public static int syncmaticaQuotaLimit = 40000000; diff --git a/patches/server/0050-Fix-TerminalConsoleAppender-NPE-error-on-server-clos.patch b/patches/server/0050-Fix-TerminalConsoleAppender-NPE-error-on-server-clos.patch index 911fb73e..c6483604 100644 --- a/patches/server/0050-Fix-TerminalConsoleAppender-NPE-error-on-server-clos.patch +++ b/patches/server/0050-Fix-TerminalConsoleAppender-NPE-error-on-server-clos.patch @@ -13,11 +13,11 @@ Fixed errors in console has no color,also fixed`Advanced terminal features are n or `Unable to create terminal` like issues diff --git a/build.gradle.kts b/build.gradle.kts -index e17498431aed5c8e683897035f7a172d71ddca96..2a180bbe6689a4dd932130777ad0acef572cf63e 100644 +index 7a5933a2bb8cde20d4d147cc2665b2e65b881c35..1916967f583ebdb70682cf754a3f641ff80cc440 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -23,7 +23,7 @@ dependencies { - // Gale end - project setup +@@ -26,7 +26,7 @@ dependencies { + // Paper start implementation("org.jline:jline-terminal-jansi:3.25.1") // Leaf - Bump Dependencies - implementation("net.minecrell:terminalconsoleappender:1.3.0") @@ -26,7 +26,7 @@ index e17498431aed5c8e683897035f7a172d71ddca96..2a180bbe6689a4dd932130777ad0acef implementation("net.kyori:ansi:1.0.3") // Manually bump beyond above transitive dep /* diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0f6ecd180c2ee18575575264366b88ff62ac11f7..f45305c0926686895e7e05ef39e8a0468b0198e8 100644 +index f2cef17007767a148d4957e654af8a655920790e..6da8bd049f3a9838383864df03a042b996f8e8a9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1270,10 +1270,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { // SparklyPaper - don't update maps if they don't have the CraftMapRenderer in the render list ++ if (!worldmap.locked && (!org.dreeam.leaf.config.modules.opt.SkipMapItemDataUpdates.enabled || worldmap.mapView.getRenderers().stream().anyMatch(mapRenderer -> mapRenderer.getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class)) && (selected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { // SparklyPaper - don't update maps if they don't have the CraftMapRenderer in the render list this.update(world, entity, worldmap); } -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 2b9e07b9e6e4f4d4e8b3e52192a983c2ad59abbf..de09de91f4d5cb4fd16aeade1c4597226e4395a6 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -208,6 +208,7 @@ public class LeafConfig { - public static int asyncEntityTrackerMaxThreads = 0; - public static int asyncEntityTrackerKeepalive = 60; - public static boolean cacheMinecartCollision = false; -+ public static boolean skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer = true; - private static void performance() { - boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning, - "Whether or not asynchronous mob spawning should be enabled.", -@@ -284,6 +285,7 @@ public class LeafConfig { - MinecraftServer.LOGGER.info("Using {} threads for Async Entity Tracker", asyncEntityTrackerMaxThreads); - cacheMinecartCollision = getBoolean("performance.cache-minecart-collision", cacheMinecartCollision, - "Cache the minecart collision result to prevent massive stacked minecart lag the server."); -+ skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer = getBoolean("performance.skip-map-item-data-updates-if-map-does-not-have-craftmaprenderer", skipMapItemDataUpdatesIfMapDoesNotHaveCraftMapRenderer); - } - - public static boolean jadeProtocol = false; +diff --git a/src/main/java/org/dreeam/leaf/config/modules/opt/SkipMapItemDataUpdates.java b/src/main/java/org/dreeam/leaf/config/modules/opt/SkipMapItemDataUpdates.java +new file mode 100644 +index 0000000000000000000000000000000000000000..014de86c0fe97d7b7ad789191dfc121419fda8a0 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/opt/SkipMapItemDataUpdates.java +@@ -0,0 +1,21 @@ ++package org.dreeam.leaf.config.modules.opt; ++ ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class SkipMapItemDataUpdates implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.PERFORMANCE; ++ } ++ ++ @Override ++ public String getBaseName() { ++ return "skip_map_item_data_updates_if_map_does_not_have_craftmaprenderer"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++} diff --git a/patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch b/patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch index 314290f1..b3812770 100644 --- a/patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch +++ b/patches/server/0062-Polpot-Make-egg-and-snowball-can-knockback-player.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Polpot: Make egg and snowball can knockback player Original project: https://github.com/PolpotMC/Polpot diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -index 440d3d72d8b2dac14f83a83caa5ae9dbf3e979b6..ce61ae16fc1413e6e12cb778fec7c8b9d2a300b4 100644 +index 440d3d72d8b2dac14f83a83caa5ae9dbf3e979b6..2aaa9458e5cef1a5b8c06e26ae8f61021d4bb4eb 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java @@ -3,6 +3,7 @@ package net.minecraft.world.entity.projectile; @@ -22,7 +22,7 @@ index 440d3d72d8b2dac14f83a83caa5ae9dbf3e979b6..ce61ae16fc1413e6e12cb778fec7c8b9 int i = entity.level().purpurConfig.snowballDamage >= 0 ? entity.level().purpurConfig.snowballDamage : entity instanceof Blaze ? 3 : 0; // Purpur entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float)i); + // Leaf start - Polpot - Make snowball can knockback player -+ if (org.dreeam.leaf.LeafConfig.snowballCanKnockback && entity instanceof ServerPlayer) { ++ if (org.dreeam.leaf.config.modules.gameplay.Knockback.snowballCanKnockback && entity instanceof ServerPlayer) { + entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); + ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ()); + } @@ -31,7 +31,7 @@ index 440d3d72d8b2dac14f83a83caa5ae9dbf3e979b6..ce61ae16fc1413e6e12cb778fec7c8b9 // Purpur start - borrowed and modified code from ThrownPotion#onHitBlock and ThrownPotion#dowseFire diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -index 785196e6f4677074890ca965e9add85ccfd0e6e3..4278daf75682875649ce3311405a2bc3fdbbaf1b 100644 +index 785196e6f4677074890ca965e9add85ccfd0e6e3..6c9680bdac576b60124b30712c388626a70b1f0e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java @@ -45,7 +45,14 @@ public class ThrownEgg extends ThrowableItemProjectile { @@ -41,7 +41,7 @@ index 785196e6f4677074890ca965e9add85ccfd0e6e3..4278daf75682875649ce3311405a2bc3 + Entity entity = entityHitResult.getEntity(); // Polpot - make egg can knockback player entityHitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F); + // Leaf start - Polpot - Make egg can knockback player -+ if (org.dreeam.leaf.LeafConfig.eggCanKnockback && entity instanceof ServerPlayer) { ++ if (org.dreeam.leaf.config.modules.gameplay.Knockback.eggCanKnockback && entity instanceof ServerPlayer) { + entity.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); + ((ServerPlayer) entity).knockback(0.4000000059604645D, this.getX() - entity.getX(), this.getZ() - entity.getZ()); + } @@ -49,19 +49,33 @@ index 785196e6f4677074890ca965e9add85ccfd0e6e3..4278daf75682875649ce3311405a2bc3 } @Override -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index de09de91f4d5cb4fd16aeade1c4597226e4395a6..94a949eb530588cdeaef31a209d3463609f88555 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -322,4 +322,11 @@ public class LeafConfig { - private static void vanillaEndTeleport() { - useVanillaEndTeleport = getBoolean("use-vanilla-end-teleport", useVanillaEndTeleport, "Vanilla End Gateway Teleport"); - } +diff --git a/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java b/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bb1887336f0a123de30b1ee92bdf82a110db2492 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/gameplay/Knockback.java +@@ -0,0 +1,24 @@ ++package org.dreeam.leaf.config.modules.gameplay; + -+ public static boolean snowballCanKnockback = false; -+ public static boolean eggCanKnockback = false; -+ private static void knockback() { -+ snowballCanKnockback = getBoolean("playerKnockback.snowball-knockback-players", snowballCanKnockback, "Make snowball can knockback players"); -+ eggCanKnockback = getBoolean("playerKnockback.egg-knockback-players", eggCanKnockback, "Make egg can knockback players"); ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class Knockback implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.GAMEPLAY; + } - } ++ ++ @Override ++ public String getBaseName() { ++ return "knockback"; ++ } ++ ++ @ConfigInfo(baseName = "snowball-knockback-players", comments = "Make snowball can knockback players") ++ public static boolean snowballCanKnockback = false; ++ ++ @ConfigInfo(baseName = "egg-knockback-players", comments = "Make egg can knockback players") ++ public static boolean eggCanKnockback = false; ++} diff --git a/patches/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch b/patches/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch index da081e8d..a1f4c47a 100644 --- a/patches/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch +++ b/patches/server/0063-Redirect-to-Gale-s-method-to-fix-plugin-incompatibil.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Redirect to Gale's method to fix plugin incompatibility diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index bdf9ee08a9661f43b7a568b2aa7e4fc7e44a48c1..8a448818d42daaa004e318a0d94bbf0a54eac367 100644 +index 8d4fbf7dd77ef5233936aa5c2bce2e63ecbdebab..42885c7f374f619fe63d9fe22a4b7f88d68008c3 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -250,6 +250,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -251,6 +251,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl static final Logger LOGGER = LogUtils.getLogger(); public static final double DEFAULT_MAX_INTERACTION_DISTANCE_SQUARED = Mth.square(6.0D); // Gale - make max interaction distance configurable @@ -16,7 +16,7 @@ index bdf9ee08a9661f43b7a568b2aa7e4fc7e44a48c1..8a448818d42daaa004e318a0d94bbf0a private static final int NO_BLOCK_UPDATES_TO_ACK = -1; private static final int TRACKED_MESSAGE_DISCONNECT_THRESHOLD = 4096; private static final Component CHAT_VALIDATION_FAILED = Component.translatable("multiplayer.disconnect.chat_validation_failed"); -@@ -331,7 +332,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -332,7 +333,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Gale start - make max interaction distance configurable public static double getMaxInteractionDistanceSquared(Level level) { var config = level.galeConfig().gameplayMechanics; diff --git a/patches/server/0064-Configurable-fix-tripwire-dupe.patch b/patches/server/0064-Configurable-fix-tripwire-dupe.patch index 1eeff6ce..aa5eb58b 100644 --- a/patches/server/0064-Configurable-fix-tripwire-dupe.patch +++ b/patches/server/0064-Configurable-fix-tripwire-dupe.patch @@ -18,7 +18,7 @@ index c615d528610168c4ad52730079f3525ab211b89e..89b3f124e4e77ca5c77fd9620cf6799c } diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -index 7f2dcf6a9e69779e6f898284b58fb1e32902000c..d7a36437fa95345bef958cb8c6112fc53be50360 100644 +index 7f2dcf6a9e69779e6f898284b58fb1e32902000c..60aba45e21f669aba15a8bac40b63faedd2b78b7 100644 --- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java @@ -162,7 +162,7 @@ public class TripWireHookBlock extends Block { @@ -26,7 +26,7 @@ index 7f2dcf6a9e69779e6f898284b58fb1e32902000c..d7a36437fa95345bef958cb8c6112fc5 flag5 |= flag6 && flag7; - if (k != i || !tripWireBeingRemoved || !flag6) // Paper - fix tripwire state inconsistency; don't update the tripwire again if being removed and not disarmed -+ if (!org.dreeam.leaf.LeafConfig.fixTripwireDupe || k != i || !tripWireBeingRemoved || !flag6) // Paper - fix tripwire state inconsistency; don't update the tripwire again if being removed and not disarmed // Leaf - Configurable fix tripwire dupe ++ if (!org.dreeam.leaf.config.modules.fixes.TripwireDupe.enabled || k != i || !tripWireBeingRemoved || !flag6) // Paper - fix tripwire state inconsistency; don't update the tripwire again if being removed and not disarmed // Leaf - Configurable fix tripwire dupe aiblockdata[k] = iblockdata2; if (k == i) { world.scheduleTick(pos, block, 10); @@ -35,24 +35,37 @@ index 7f2dcf6a9e69779e6f898284b58fb1e32902000c..d7a36437fa95345bef958cb8c6112fc5 TripWireHookBlock.emitState(world, pos, flag4, flag5, flag2, flag3); if (!beingRemoved) { // Paper - fix tripwire state inconsistency - if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update -+ if (!org.dreeam.leaf.LeafConfig.fixTripwireDupe || world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update // Leaf - Configurable fix tripwire dupe ++ if (!org.dreeam.leaf.config.modules.fixes.TripwireDupe.enabled || world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update // Leaf - Configurable fix tripwire dupe world.setBlock(pos, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection), 3); if (flag1) { TripWireHookBlock.notifyNeighbors(block, world, pos, enumdirection); -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 94a949eb530588cdeaef31a209d3463609f88555..5e362d086d64ec19dd9bffd680cc82d20164c570 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -329,4 +329,9 @@ public class LeafConfig { - snowballCanKnockback = getBoolean("playerKnockback.snowball-knockback-players", snowballCanKnockback, "Make snowball can knockback players"); - eggCanKnockback = getBoolean("playerKnockback.egg-knockback-players", eggCanKnockback, "Make egg can knockback players"); - } +diff --git a/src/main/java/org/dreeam/leaf/config/modules/fixes/TripwireDupe.java b/src/main/java/org/dreeam/leaf/config/modules/fixes/TripwireDupe.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6d4887d9a523086aabb33c6959d3821b675b2e1a +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/fixes/TripwireDupe.java +@@ -0,0 +1,21 @@ ++package org.dreeam.leaf.config.modules.fixes; + -+ public static boolean fixTripwireDupe = true; -+ private static void tripwireDupe() { -+ fixTripwireDupe = getBoolean("gameplay.fix-tripwire-dupe", fixTripwireDupe); ++import org.dreeam.leaf.config.ConfigInfo; ++import org.dreeam.leaf.config.EnumConfigCategory; ++import org.dreeam.leaf.config.IConfigModule; ++ ++public class TripwireDupe implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.FIXES; + } - } ++ ++ @Override ++ public String getBaseName() { ++ return "fix_tripwire_dupe"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++} diff --git a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java b/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java index 704791c80d42a653c8e02440d46cd96e6adb5fb5..8226f1f9b21e97c882248bc7227861381b1e5a2f 100644 --- a/src/main/java/org/galemc/gale/configuration/GaleWorldConfiguration.java diff --git a/patches/server/0067-Including-5s-in-getTPS.patch b/patches/server/0067-Including-5s-in-getTPS.patch index 49cea0bf..e1d7e936 100644 --- a/patches/server/0067-Including-5s-in-getTPS.patch +++ b/patches/server/0067-Including-5s-in-getTPS.patch @@ -5,29 +5,49 @@ Subject: [PATCH] Including 5s in getTPS() diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index a1317e374066d2abe20064bc47e20f4b19db9705..cee77b134c40c6d3e52d32a5fbf0888d121fd00f 100644 +index a1317e374066d2abe20064bc47e20f4b19db9705..9c447419c13c142731b6de0a88870eb2a991ddfb 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -3137,6 +3137,8 @@ public final class CraftServer implements Server { @Override public double[] getTPS() { -+ if (org.dreeam.leaf.LeafConfig.including5sIngetTPS)return getTPSIncluding5SecondAverage(); // Leaf - Including 5s in getTPS() ++ if (org.dreeam.leaf.config.modules.misc.Including5sIngetTPS.enabled) return getTPSIncluding5SecondAverage(); // Leaf - Including 5s in getTPS() + return new double[] { net.minecraft.server.MinecraftServer.getServer().tps1.getAverage(), net.minecraft.server.MinecraftServer.getServer().tps5.getAverage(), -diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java -index 5e362d086d64ec19dd9bffd680cc82d20164c570..c38b6f8df27d37ffc48452deb85fe2f283fa1661 100644 ---- a/src/main/java/org/dreeam/leaf/LeafConfig.java -+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java -@@ -334,4 +334,9 @@ public class LeafConfig { - private static void tripwireDupe() { - fixTripwireDupe = getBoolean("gameplay.fix-tripwire-dupe", fixTripwireDupe); - } +diff --git a/src/main/java/org/dreeam/leaf/config/modules/misc/Including5sIngetTPS.java b/src/main/java/org/dreeam/leaf/config/modules/misc/Including5sIngetTPS.java +new file mode 100644 +index 0000000000000000000000000000000000000000..54a27e0f44000511ee2695e43700af7770d78333 +--- /dev/null ++++ b/src/main/java/org/dreeam/leaf/config/modules/misc/Including5sIngetTPS.java +@@ -0,0 +1,28 @@ ++package org.dreeam.leaf.config.modules.misc; + -+ public static boolean including5sIngetTPS = true; -+ private static void including5sInTPS() { -+ including5sIngetTPS = getBoolean("including-5s-in-getTPS", including5sIngetTPS); ++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 Including5sIngetTPS implements IConfigModule { ++ ++ @Override ++ public EnumConfigCategory getCategory() { ++ return EnumConfigCategory.MISC; + } - } ++ ++ @Override ++ public String getBaseName() { ++ return "including_5s_in_get_tps"; ++ } ++ ++ @ConfigInfo(baseName = "enabled") ++ public static boolean enabled = true; ++ ++ @Override ++ public void onLoaded(CommentedFileConfig config) { ++ config.setComment("", """ ++ """); ++ } ++}