9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-29 11:59:24 +00:00

Updated Upstream (Leaf API)

This commit is contained in:
Dreeam
2024-05-25 14:37:44 +08:00
parent c6ef60f633
commit aa37aa727a
18 changed files with 149 additions and 1388 deletions

View File

@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 21 May 2024 11:43:49 +0800
Subject: [PATCH] Rebrand
diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
index fd5d9881abfd930bb883120f018f76dc78b62b14..dac207f2f5ae1838ca1b5092f7fe032adc038849 100644
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
@@ -214,7 +214,7 @@ public class VersionCommand extends BukkitCommand {
String version = Bukkit.getVersion();
// Paper start
if (version.startsWith("null")) { // running from ide?
- setVersionMessage(Component.text("Unknown version, custom build?", NamedTextColor.YELLOW));
+ setVersionMessage(Component.text("* Unknown version, custom build?", NamedTextColor.RED)); // Leaf - Purpur - Clean up version command output
return;
}
setVersionMessage(getVersionFetcher().getVersionMessage(version));

View File

@@ -7,20 +7,20 @@ Original license: GPL v3
Original project: https://github.com/pufferfish-gg/Pufferfish
diff --git a/build.gradle.kts b/build.gradle.kts
index a2f7dbcd9ab971e5c4b809e7c9dd39e9b1077af6..2f8d0f4a592536ab8d3b5a95093d118137ba65de 100644
index a2f7dbcd9ab971e5c4b809e7c9dd39e9b1077af6..e5c0cdf8f46494f37c3327265d6b2d80a9979e24 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -46,6 +46,7 @@ dependencies {
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
api("org.apache.logging.log4j:log4j-api:$log4jVersion")
api("org.slf4j:slf4j-api:$slf4jVersion")
+ api("io.sentry:sentry:6.29.0") // Pufferfish
+ api("io.sentry:sentry:5.4.0") // Pufferfish
implementation("org.ow2.asm:asm:9.4")
implementation("org.ow2.asm:asm-commons:9.4")
diff --git a/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac6be3306f
index 0000000000000000000000000000000000000000..c7772aac00f6db664f7a5673bc2585fa025e6aad
--- /dev/null
+++ b/src/main/java/gg/pufferfish/pufferfish/sentry/SentryContext.java
@@ -0,0 +1,165 @@
@@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac
+ public static void setPluginContext(@Nullable Plugin plugin) {
+ if (plugin != null) {
+ ThreadContext.put("pufferfishsentry_pluginname", plugin.getName());
+ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getDescription().getVersion());
+ ThreadContext.put("pufferfishsentry_pluginversion", plugin.getPluginMeta().getVersion());
+ }
+ }
+
@@ -102,7 +102,7 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac
+ if (player != null) {
+ setSenderContext(player);
+ }
+ } catch (Exception e) {
+ } catch (Exception ignored) {
+ } // We can't really safely log exceptions.
+
+ ThreadContext.put("pufferfishsentry_eventdata", GSON.toJson(serializeFields(event)));
@@ -134,7 +134,7 @@ index 0000000000000000000000000000000000000000..364e20dfb1a141e86ae64663cc5f31ac
+ } else {
+ fields.put(fieldName, "<null>");
+ }
+ } catch (Exception e) {
+ } catch (Exception ignored) {
+ } // We can't really safely log exceptions.
+ }
+ return fields;

View File

@@ -6,8 +6,12 @@ Subject: [PATCH] Purpur API Changes
Commit: f6fd5f6ba6e672bfdbc79def7e8598d984ec8b3c
Patches below are removed in this patch:
Pufferfish-API-Changes.patch
Fix-pufferfish-issues.patch
Build-System-Changes.patch
Clean-up-version-command-output.patch
Remove-Timings.patch
Add-log-suppression-for-LibraryLoader.patch
Original license: MIT
Original project: https://github.com/PurpurMC/Purpur
@@ -717,34 +721,6 @@ index ac9a28922f8a556944a4c3649d74c32c622f0cb0..e43d0e0a2c5edfcc82a677b6c4db9314
// Paper start - Plugins do weird things to workaround normal registration
if (target.timings == null) {
target.timings = co.aikar.timings.TimingsManager.getCommandTiming(null, target);
diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
index fd5d9881abfd930bb883120f018f76dc78b62b14..d3dadad49df09e85c724c93e8cc88da2c985e9b4 100644
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
@@ -214,7 +214,7 @@ public class VersionCommand extends BukkitCommand {
String version = Bukkit.getVersion();
// Paper start
if (version.startsWith("null")) { // running from ide?
- setVersionMessage(Component.text("Unknown version, custom build?", NamedTextColor.YELLOW));
+ setVersionMessage(Component.text("* Unknown version, custom build?", NamedTextColor.RED)); // Purpur
return;
}
setVersionMessage(getVersionFetcher().getVersionMessage(version));
@@ -255,9 +255,11 @@ public class VersionCommand extends BukkitCommand {
// Paper start
private void setVersionMessage(final @NotNull Component msg) {
lastCheck = System.currentTimeMillis();
- final Component message = Component.textOfChildren(
- Component.text(Bukkit.getVersionMessage(), NamedTextColor.WHITE),
- Component.newline(),
+ // Purpur start
+ int distance = getVersionFetcher().distance();
+ final Component message = Component.join(net.kyori.adventure.text.JoinConfiguration.separator(Component.newline()),
+ ChatColor.parseMM("<grey>Current: %s%s*", distance == 0 ? "<green>" : distance > 0 ? "<yellow>" : "<red>", Bukkit.getVersion()),
+ // Purpur end
msg
);
this.versionMessage = Component.text()
diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java
index 455ff52d90565838fe7640c3f045b27082a6c2f1..45f5493eebfecf56b7c0ef4659c078dfc62c0612 100644
--- a/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Bump Dependencies
diff --git a/build.gradle.kts b/build.gradle.kts
index 2f8d0f4a592536ab8d3b5a95093d118137ba65de..d005dd963289cecad7fa072d2531165bd2fc9ef3 100644
index e5c0cdf8f46494f37c3327265d6b2d80a9979e24..b807337908c9f35c5ca1fafffe65da6d784732a5 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,8 +11,8 @@ java {
@@ -42,7 +42,7 @@ index 2f8d0f4a592536ab8d3b5a95093d118137ba65de..d005dd963289cecad7fa072d2531165b
apiAndDocs("net.kyori:adventure-text-minimessage")
@@ -48,30 +48,32 @@ dependencies {
api("org.slf4j:slf4j-api:$slf4jVersion")
api("io.sentry:sentry:6.29.0") // Pufferfish
api("io.sentry:sentry:5.4.0") // Pufferfish
- implementation("org.ow2.asm:asm:9.4")
- implementation("org.ow2.asm:asm-commons:9.4")

View File

@@ -1,15 +1,15 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bjarne Koll <lynxplay101@gmail.com>
Date: Thu, 9 Dec 2021 01:53:30 +0100
Subject: [PATCH] KTP: Optimize Spigot event bus
Subject: [PATCH] KTP: Allow unknown event thread execution
Original license: GPL v3
Original project: https://github.com/lynxplay/ktp
This patch contains a lot of small optimizations to the spigot event bus
to improve its speed as much as possible, allowing for a large amount of
events to be published by the server without impacting the overall
performance too much.
This patch allows events to actively define that they may or may not be
called on the main thread of the server. This is preferred over passing
the "asyncness" of the event as async bool parameter to the event instance
every time.
diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java
index 8ec56cd6b8e0f5c5dd8c7c88b4671e18dcf109d0..caae79275802bc5e5a5385d6a11903dfa84325d1 100644

View File

@@ -7,33 +7,20 @@ Original license: MIT
Original project: https://github.com/KeYiMC/KeYi
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 877ed7bea937e0be1c404d5ab5cef8fce5e6ac17..1be72e3f0dfb3a8f09af4d913cbe0dc87f30d232 100644
index 877ed7bea937e0be1c404d5ab5cef8fce5e6ac17..46d8d8e11448613de3caa0a54613c8d028673ad0 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -8,8 +8,11 @@ import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
-
import org.bukkit.BanEntry;
+// KeYi start
+import java.util.concurrent.CompletableFuture;
+import net.kyori.adventure.text.Component;
+// KeYi end
import org.bukkit.DyeColor;
import org.bukkit.Effect;
import org.bukkit.GameMode;
@@ -3424,4 +3427,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
@@ -3424,4 +3424,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
sendDeathScreen(message);
}
// Purpur end
+
+ // KeYi start
+ // Leaf start - KeYi - Player Skull API
+ /**
+ * Get a skull item of a player.
+ * This method runs on main thread, which may freeze the server.
+ *
+ * @return A ItemStack of the skull of the player
+ * @return A skull ItemStack of the player
+ */
+ ItemStack getSkull();
+
@@ -41,8 +28,8 @@ index 877ed7bea937e0be1c404d5ab5cef8fce5e6ac17..1be72e3f0dfb3a8f09af4d913cbe0dc8
+ * Get a skull item of a player.
+ * This method runs on main thread, which may freeze the server.
+ *
+ * @return A CompletableFuture the of ItemStack of the skull of the player
+ * @return A CompletableFuture of the skull ItemStack of the player
+ */
+ CompletableFuture<ItemStack> getSkullAsynchronously();
+ // KeYi end
+ // Leaf end - KeYi
}

View File

@@ -7,10 +7,10 @@ Original license: MIT
Original project: https://github.com/Cryptite/Slice
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 1be72e3f0dfb3a8f09af4d913cbe0dc87f30d232..abcb9f86459395ba3ec7ac186079451951f6b52e 100644
index 46d8d8e11448613de3caa0a54613c8d028673ad0..8d7f596152096e2be935d5f3af96045db403735d 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -3170,6 +3170,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
@@ -3167,6 +3167,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
String getClientBrandName();
// Paper end
@@ -24,7 +24,7 @@ index 1be72e3f0dfb3a8f09af4d913cbe0dc87f30d232..abcb9f86459395ba3ec7ac1860794519
+ */
+ // Slice start
+ @org.jetbrains.annotations.ApiStatus.Experimental
+ void teleportWithoutRespawn(Location location);
+ void teleportWithoutRespawn(@NotNull Location location);
+ // Slice end
+
// Paper start - Teleport API

View File

@@ -0,0 +1,41 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sat, 3 Feb 2024 18:45:53 -0500
Subject: [PATCH] Configurable LibraryLoader maven repos
TODO - Dreeam: Support multi maven repos for lib downloading.
Add JVM flag `-DLeaf.library-download-repo=link` to choose library download repo link.
e.g. `-DLeaf.library-download-repo=https://maven.aliyun.com/repository/public`
diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
index a749856a6a4189d1f5aa3f193f5fa6a9dd7b13f1..142e17fca2e2dc5e748c9600f500db009f07b62d 100644
--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
@@ -46,6 +46,7 @@ public class LibraryLoader
private final RepositorySystem repository;
private final DefaultRepositorySystemSession session;
private final List<RemoteRepository> repositories;
+ private final String repositoryAddress = System.getProperty("Leaf.library-download-repo") != null ? System.getProperty("Leaf.library-download-repo") : "https://repo.maven.apache.org/maven2"; // Leaf - Configurable maven repos
public LibraryLoader(@NotNull Logger logger)
{
@@ -71,7 +72,17 @@ public class LibraryLoader
} );
session.setReadOnly();
- this.repositories = repository.newResolutionRepositories( session, Arrays.asList( new RemoteRepository.Builder( "central", "default", "https://repo.maven.apache.org/maven2" ).build() ) );
+ // Leaf start - Configurable maven repos
+ this.repositories = repository.newResolutionRepositories( session, List.of( new RemoteRepository.Builder( "central", "default", repositoryAddress ).build() ) );
+ /* // Dreeam TODO
+ this.repositories = repository.newResolutionRepositories(session, List.of(
+ new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2").build(),
+ new RemoteRepository.Builder("aliyun", "default", "https://maven.aliyun.com/repository/public").build(),
+ new RemoteRepository.Builder("tencentclound", "default", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/").build(),
+ new RemoteRepository.Builder("huaweicloud", "default", "https://repo.huaweicloud.com/repository/maven/").build()
+ ));
+ */
+ // Leaf end - Configurable maven repos
}
@Nullable

View File

@@ -5,7 +5,7 @@ Subject: [PATCH] Rebrand
diff --git a/build.gradle.kts b/build.gradle.kts
index 4466f21a83cb9ddca7309a194afcb8eded92de81..cc9c8cbefbce8cc31effe914227b78272374eae1 100644
index 309204683e642ddfaab20c9d685bf1175bd65e28..ac1d39ce2923716336c2ed31b9b7f1d93a9d5e30 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -15,7 +15,7 @@ val alsoShade: Configuration by configurations.creating
@@ -27,7 +27,7 @@ index 4466f21a83cb9ddca7309a194afcb8eded92de81..cc9c8cbefbce8cc31effe914227b7827
"Specification-Title" to "Bukkit",
"Specification-Version" to project.version,
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 88102f6ba8352a080125512d0bbfacdf779f4f38..1ea04a20247c7154fc3e59693f28b993ff78e2b8 100644
index 88102f6ba8352a080125512d0bbfacdf779f4f38..fe50cc484ebfe4d3ab8795c222b2abd45fe64310 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
@@ -593,7 +593,7 @@ public class Metrics {
@@ -35,7 +35,7 @@ index 88102f6ba8352a080125512d0bbfacdf779f4f38..1ea04a20247c7154fc3e59693f28b993
// Only start Metrics, if it's enabled in the config
if (config.getBoolean("enabled", true)) {
- Metrics metrics = new Metrics("Gale", serverUUID, logFailedRequests, Bukkit.getLogger()); // Gale - branding changes - metrics
+ Metrics metrics = new Metrics("Leaf", serverUUID, logFailedRequests, Bukkit.getLogger()); // Gale - branding changes - metrics // Leaf - rebrand
+ Metrics metrics = new Metrics("Leaf", serverUUID, logFailedRequests, Bukkit.getLogger()); // Gale - branding changes - metrics // Leaf
metrics.addCustomChart(new Metrics.SimplePie("minecraft_version", () -> {
String minecraftVersion = Bukkit.getVersion();
@@ -44,18 +44,18 @@ index 88102f6ba8352a080125512d0bbfacdf779f4f38..1ea04a20247c7154fc3e59693f28b993
metrics.addCustomChart(new Metrics.SingleLineChart("players", () -> Bukkit.getOnlinePlayers().size()));
metrics.addCustomChart(new Metrics.SimplePie("online_mode", () -> Bukkit.getOnlineMode() ? "online" : "offline"));
- final String galeVersion; // Gale - branding changes - metrics
+ final String leafVersion; // Gale - branding changes - metrics // Leaf - rebrand
+ final String leafVersion; // Gale - branding changes - metrics // Leaf
final String implVersion = org.bukkit.craftbukkit.Main.class.getPackage().getImplementationVersion();
if (implVersion != null) {
final String buildOrHash = implVersion.substring(implVersion.lastIndexOf('-') + 1);
- galeVersion = "git-Gale-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Gale - branding changes - metrics
+ leafVersion = "git-Leaf-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Gale - branding changes - metrics // Leaf - rebrand
+ leafVersion = "git-Leaf-%s-%s".formatted(Bukkit.getServer().getMinecraftVersion(), buildOrHash); // Gale - branding changes - metrics // Leaf
} else {
- galeVersion = "unknown"; // Gale - branding changes - metrics
+ leafVersion = "unknown"; // Gale - branding changes - metrics // Leaf - rebrand
+ leafVersion = "unknown"; // Gale - branding changes - metrics // Leaf
}
- metrics.addCustomChart(new Metrics.SimplePie("gale_version", () -> galeVersion)); // Gale - branding changes - metrics
+ metrics.addCustomChart(new Metrics.SimplePie("leaf_version", () -> leafVersion)); // Gale - branding changes - metrics // Leaf - rebrand
+ metrics.addCustomChart(new Metrics.SimplePie("leaf_version", () -> leafVersion)); // Gale - branding changes - metrics // Leaf
metrics.addCustomChart(new Metrics.DrilldownPie("java_version", () -> {
Map<String, Map<String, Integer>> map = new HashMap<>(2); // Gale - metrics - reduce HashMap capacity
@@ -72,6 +72,21 @@ index e45e6b44b2a8f2cdae6e0048a812b92126aa17ca..b5f3f213da8a40d5184098af017c8e26
.variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history"))
.completer(new ConsoleCommandCompleter(this.server))
.option(LineReader.Option.COMPLETE_IN_WORD, true);
diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java
index abe37c7c3c6f5ab73afd738ec78f06d7e4d2ed96..13aa061d5a31cb922b07a92836e3938a2ab66719 100644
--- a/src/main/java/net/minecraft/CrashReport.java
+++ b/src/main/java/net/minecraft/CrashReport.java
@@ -123,6 +123,10 @@ public class CrashReport {
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append("---- Minecraft Crash Report ----\n");
+ // Leaf start - Purpur
+ stringbuilder.append("// ");
+ stringbuilder.append("// DO NOT REPORT THIS TO PAPER OR GALE! REPORT TO LEAF INSTEAD!");
+ // Leaf end - Purpur
stringbuilder.append("// ");
stringbuilder.append(CrashReport.getErrorComment());
stringbuilder.append("\n\n");
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 7183d8013ce2b7c4ab404f6a181f6415a1bf673e..3bee751a36c1aaab9b9a738edac80b4d2853bdd7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -86,7 +101,7 @@ index 7183d8013ce2b7c4ab404f6a181f6415a1bf673e..3bee751a36c1aaab9b9a738edac80b4d
while (this.getRunningThread().isAlive()) {
this.getRunningThread().stop();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 5d3a5bdd8e223ff45320d3a8ac9e57d5d7ff02bf..f44bb05c9478ec9a4d9c512fa1b6fc3a8acd5949 100644
index e332b34cfbc1c15b14141a6ddd070656805dd06c..0651aaa8abf43a94ed06e591fd082a961aabc01f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -268,7 +268,7 @@ import javax.annotation.Nullable; // Paper
@@ -112,7 +127,7 @@ index 3dd7ee2e099199550b885947d33d8b27901ac373..65566adec52a51df05c5ce9c1e673f3c
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index 0b5979723bb30f9011ac64c36d894aa41713ec9b..17e3ee3a73a2347e9f0baa0ed1640a3b0e75ed16 100644
index 0b5979723bb30f9011ac64c36d894aa41713ec9b..e220f5601f6b92b7b280ce8ebe64117d30192b0e 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning {
@@ -120,23 +135,10 @@ index 0b5979723bb30f9011ac64c36d894aa41713ec9b..17e3ee3a73a2347e9f0baa0ed1640a3b
String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.galemc.gale/gale-api/pom.properties"); // Gale - branding changes
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.dreeam.leaf/leaf-api/pom.properties"); // Gale - branding changes // Leaf
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/cn.dreeam.leaf/leaf-api/pom.properties"); // Gale - branding changes // Leaf
Properties properties = new Properties();
if (stream != null) {
diff --git a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java
index 7fee1c2779ab390586b2d3f75f56890846323500..d55adec004fd733859a75b34ce54e1f10b7336fc 100644
--- a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java
+++ b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java
@@ -68,7 +68,7 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher {
// Gale end - branding changes - version fetcher
final Component history = getHistory();
- return history != null ? TextComponent.ofChildren(updateMessage, Component.newline(), history) : updateMessage;
+ return history != null ? Component.textOfChildren(updateMessage, Component.newline(), history) : updateMessage;
}
protected @Nullable String getMinecraftVersion() { // Gale - branding changes - version fetcher
diff --git a/src/main/java/org/galemc/gale/version/GaleVersionFetcher.java b/src/main/java/org/galemc/gale/version/GaleVersionFetcher.java
index 9b4bc17fed9dc7251159687082cf8de60dd49ba4..7d45fa394da75ae3d0c7afc14a7a6fe383fc0197 100644
--- a/src/main/java/org/galemc/gale/version/GaleVersionFetcher.java
@@ -151,9 +153,18 @@ index 9b4bc17fed9dc7251159687082cf8de60dd49ba4..7d45fa394da75ae3d0c7afc14a7a6fe3
}
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
index 08bdaab86269b0a24e61b3c9d69c18aca1a1d1f7..dc306e27b75d4b20a0ea38d01287dd94acafc1ac 100644
index b66caf636cbb4b6a56584ad710600ad2c3fb17d2..73328d18344e0384e2f94a382f9e2c3cfe511b8d 100644
--- a/src/main/java/org/spigotmc/WatchdogThread.java
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -96,7 +96,7 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
private WatchdogThread(long timeoutTime, boolean restart)
{
- super( "Paper Watchdog Thread" );
+ super( "Watchdog Thread" ); // Leaf - Purpur - use a generic name
this.timeoutTime = timeoutTime;
this.restart = restart;
earlyWarningEvery = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningEvery, timeoutTime); // Paper
@@ -160,15 +160,15 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
We do not want people to report thread issues to Paper,
but we do want people to report thread issues to Gale.

View File

@@ -4,6 +4,10 @@ Date: Wed, 24 May 2023 06:00:03 +0800
Subject: [PATCH] Purpur Server Changes
Commit: f6fd5f6ba6e672bfdbc79def7e8598d984ec8b3c
with some fixes backport from ver/1.20.6:
Fix bee count payload lag/crash exploit and make it configurable. (#1491) https://github.com/PurpurMC/Purpur/commit/5b468f25626e796aee99ddef87509861a58780a7
only show armorstand name if it's custom, fixes #1514 https://github.com/PurpurMC/Purpur/commit/be47af0884f583ac90968d4f1e90275cc383bd9d
reparse minimessage from serialized playerlist component, closes #1515 https://github.com/PurpurMC/Purpur/commit/ba950ad7758d4da6ccc26f578521ab4a07a2402d
Patches below are removed in this patch:
MC-238526-Fix-spawner-not-spawning-water-animals-cor.patch
@@ -26,7 +30,7 @@ Spark-Profiler.patch
Halloween-options-and-optimizations.patch
diff --git a/build.gradle.kts b/build.gradle.kts
index 898aa6d1198da0c50a274ea0c26aaa4518f9395d..d490236de781f8e10058acc265d8c6032e7048a5 100644
index 566a23c88d7a7b156ecedd75096a16b679247df8..03e817485d50d63802dcbbacd972ffabf8612dd8 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -54,6 +54,10 @@ dependencies {
@@ -785,7 +789,7 @@ index d601d287e94a59ff93b8a83a44dac02544d211df..0ff3b06a98b2f4514b2d861b92dd70fe
itemstack1.setCount(1);
entityitem = entityplayer.drop(itemstack1, false, false, false); // 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 b66e708b788800ba97c25104770904ffdc460fcc..505386640a12219dd19e27e58691701b74b55a28 100644
index b66e708b788800ba97c25104770904ffdc460fcc..0b13a32dc14191a14ab2b30d34492295f5b6100f 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
@@ -848,7 +852,7 @@ index b66e708b788800ba97c25104770904ffdc460fcc..505386640a12219dd19e27e58691701b
if (org.dreeam.leaf.LeafConfig.enableAsyncMobSpawning) mobSpawnExecutor.start(); // Pufferfish
+ org.purpurmc.purpur.task.BossBarTask.startAll(); // Purpur
+ org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur
+ if (org.purpurmc.purpur.PurpurConfig.beeCountPayload) org.purpurmc.purpur.task.BeehiveTask.instance().register(); // Purpur
return true;
}
}
@@ -1221,7 +1225,7 @@ index 5d6c0f5d2d993ae3a044a1a02716a2662e9080d0..b77a84a5ab85839e37aee24da0f4356b
}
// Paper end
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index e430cb871489ce1e7c11a84002508480417daa4e..54807be5d539fd768f9cb7a8ce912983ae328b46 100644
index e430cb871489ce1e7c11a84002508480417daa4e..7206e59afd73e8b00993518a671dd2de1af34242 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -279,6 +279,11 @@ public class ServerPlayer extends Player {
@@ -1457,7 +1461,7 @@ index e430cb871489ce1e7c11a84002508480417daa4e..54807be5d539fd768f9cb7a8ce912983
+ if (afk) {
+ getBukkitEntity().setPlayerListName(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix + prefix + scoreboardName + suffix + org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, true);
+ } else {
+ getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix);
+ getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix, true);
+ }
+ }
+
@@ -13984,7 +13988,7 @@ index d7a0cbde8f8c99276307502674c71463fbe7e89c..3500c56cb85d8c76b2acd77976d374ea
// CraftBukkit start
Level world = pointer.getLevel();
diff --git a/src/main/java/net/minecraft/world/item/ArmorStandItem.java b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32bdb1ad44f 100644
index 7cffc64573008502bdd14ae4906fe51166b12fb3..30502ffb3109ed96d3b51b9045af55288b66c3f0 100644
--- a/src/main/java/net/minecraft/world/item/ArmorStandItem.java
+++ b/src/main/java/net/minecraft/world/item/ArmorStandItem.java
@@ -58,6 +58,14 @@ public class ArmorStandItem extends Item {
@@ -13994,7 +13998,7 @@ index 7cffc64573008502bdd14ae4906fe51166b12fb3..1feafdbb48cf760cb6ebf95d5be2c32b
+ // Purpur start
+ if (world.purpurConfig.persistentDroppableEntityDisplayNames && itemstack.hasCustomHoverName()) {
+ entityarmorstand.setCustomName(itemstack.getHoverName());
+ if (world.purpurConfig.armorstandSetNameVisible) {
+ if (world.purpurConfig.armorstandSetNameVisible && entityarmorstand.getCustomName() != null) {
+ entityarmorstand.setCustomNameVisible(true);
+ }
+ }
@@ -18650,14 +18654,14 @@ index 2959f713ce75a1df9c6c7cf5e021690cfcb6e1e7..3fa9539cfb2c35beeba6d44fa05cee97
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "defaultgamemode", "Allows the user to change the default gamemode of the server", PermissionDefault.OP, commands);
DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "seed", "Allows the user to view the seed of the world", PermissionDefault.OP, commands);
diff --git a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java
index d55adec004fd733859a75b34ce54e1f10b7336fc..5fdb227acfd1d8f55b770c8a66e97494c36db33c 100644
index 7fee1c2779ab390586b2d3f75f56890846323500..5fdb227acfd1d8f55b770c8a66e97494c36db33c 100644
--- a/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java
+++ b/src/main/java/org/galemc/gale/version/AbstractPaperVersionFetcher.java
@@ -68,7 +68,7 @@ public abstract class AbstractPaperVersionFetcher implements VersionFetcher {
// Gale end - branding changes - version fetcher
final Component history = getHistory();
- return history != null ? Component.textOfChildren(updateMessage, Component.newline(), history) : updateMessage;
- return history != null ? TextComponent.ofChildren(updateMessage, Component.newline(), history) : updateMessage;
+ return history != null ? Component.join(net.kyori.adventure.text.JoinConfiguration.separator(Component.newline()), history, updateMessage) : updateMessage; // Purpur
}
@@ -18690,10 +18694,10 @@ index d55adec004fd733859a75b34ce54e1f10b7336fc..5fdb227acfd1d8f55b770c8a66e97494
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..45cb38d9e8b20a8ee4421e0b4fd6313138b6b910
index 0000000000000000000000000000000000000000..8299aab5c29c8c6d996087537d9522b653b03ffa
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java
@@ -0,0 +1,655 @@
@@ -0,0 +1,660 @@
+package org.purpurmc.purpur;
+
+import com.google.common.base.Throwables;
@@ -19157,6 +19161,11 @@ index 0000000000000000000000000000000000000000..45cb38d9e8b20a8ee4421e0b4fd63131
+ allowWaterPlacementInTheEnd = getBoolean("settings.allow-water-placement-in-the-end", allowWaterPlacementInTheEnd);
+ }
+
+ public static boolean beeCountPayload = false;
+ private static void beeCountPayload() {
+ beeCountPayload = getBoolean("settings.bee-count-payload", beeCountPayload);
+ }
+
+ public static boolean loggerSuppressInitLegacyMaterialError = false;
+ public static boolean loggerSuppressIgnoredAdvancementWarnings = false;
+ public static boolean loggerSuppressUnrecognizedRecipeErrors = false;
@@ -19351,7 +19360,7 @@ index 0000000000000000000000000000000000000000..45cb38d9e8b20a8ee4421e0b4fd63131
+}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..2056fc462ab11a86f17c630e868b70eea4f35553
index 0000000000000000000000000000000000000000..4eae5f4e963bc0267150cdf3ee0949ec1de00a8d
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -0,0 +1,3255 @@
@@ -19455,7 +19464,7 @@ index 0000000000000000000000000000000000000000..2056fc462ab11a86f17c630e868b70ee
+ }
+
+ public float armorstandStepHeight = 0.0F;
+ public boolean armorstandSetNameVisible = true;
+ public boolean armorstandSetNameVisible = false;
+ public boolean armorstandFixNametags = false;
+ public boolean armorstandMovement = true;
+ public boolean armorstandWaterMovement = true;
@@ -24148,10 +24157,10 @@ index 0000000000000000000000000000000000000000..c038fb2bbb0f0e78380bc24bbd6348b8
+}
diff --git a/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ebbaf5faa92a88bfb4d61298951e5b74157d1e1
index 0000000000000000000000000000000000000000..9fca0e0239244eb1d63e6bd9a467aa00de449b12
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/task/BeehiveTask.java
@@ -0,0 +1,81 @@
@@ -0,0 +1,85 @@
+package org.purpurmc.purpur.task;
+
+import com.google.common.io.ByteArrayDataInput;
@@ -24209,6 +24218,10 @@ index 0000000000000000000000000000000000000000..2ebbaf5faa92a88bfb4d61298951e5b7
+
+ ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
+
+ // targeted block info max range specified in client at net.minecraft.client.gui.hud.DebugHud#render
+ if (!pos.getCenter().closerThan(serverPlayer.position(), 20)) return; // Targeted Block info max range is 20
+ if (serverPlayer.level().getChunkIfLoaded(pos) == null) return;
+
+ BlockEntity blockEntity = serverPlayer.level().getBlockEntity(pos);
+ if (!(blockEntity instanceof BeehiveBlockEntity beehive)) {
+ return;

View File

@@ -1,186 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: peaches94 <peachescu94@gmail.com>
Date: Sun, 10 Jul 2022 13:29:20 -0500
Subject: [PATCH] Petal: reduce work done by game event system
Original license: GPL v3
Original project: https://github.com/Bloom-host/Petal
1. going into game event dispatching can be expensive so run the checks before dispatching
2. EuclideanGameEventListenerRegistry is not used concurrently so we ban that usage for improved performance with allays
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
index a606aed406551f4d3cc0bf09d6e231d87fe00f53..01babdf2c82d019589c38b73a10ad7afeebd32d2 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java
@@ -126,6 +126,13 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi
world.playSound((Player) null, pos, SoundEvents.SCULK_CATALYST_BLOOM, SoundSource.BLOCKS, 2.0F, 0.6F + random.nextFloat() * 0.4F);
}
+ // petal start
+ @Override
+ public boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
+ return !this.isRemoved() && gameEvent == GameEvent.ENTITY_DIE && context.sourceEntity() instanceof LivingEntity;
+ }
+ // petal end
+
private void tryAwardItSpreadsAdvancement(Level world, LivingEntity deadEntity) {
LivingEntity entityliving1 = deadEntity.getLastHurtByMob();
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
index 901938201c1abee1c88e217d2c1ba1a2d147420e..e0a90ee2c28dc67e33db8f3b599cfb9cef294553 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -80,7 +80,18 @@ public class LevelChunk extends ChunkAccess {
private Supplier<FullChunkStatus> fullStatus;
@Nullable
private LevelChunk.PostLoadProcessor postLoad;
- private final Int2ObjectMap<GameEventListenerRegistry> gameEventListenerRegistrySections;
+ // petal start
+ private final GameEventListenerRegistry[] gameEventListenerRegistrySections;
+ private static final int GAME_EVENT_DISPATCHER_RADIUS = 2;
+
+ private static int getGameEventSectionIndex(int sectionIndex) {
+ return sectionIndex + GAME_EVENT_DISPATCHER_RADIUS;
+ }
+
+ private static int getGameEventSectionLength(int sectionCount) {
+ return sectionCount + (GAME_EVENT_DISPATCHER_RADIUS * 2);
+ }
+ // petal end
private final LevelChunkTicks<Block> blockTicks;
private final LevelChunkTicks<Fluid> fluidTicks;
@@ -108,7 +119,7 @@ public class LevelChunk extends ChunkAccess {
// Paper end - rewrite light engine
this.tickersInLevel = Maps.newHashMap();
this.level = (ServerLevel) world; // CraftBukkit - type
- this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap();
+ this.gameEventListenerRegistrySections = new GameEventListenerRegistry[getGameEventSectionLength(this.getSectionsCount())]; // petal
Heightmap.Types[] aheightmap_type = Heightmap.Types.values();
int j = aheightmap_type.length;
@@ -398,9 +409,23 @@ public class LevelChunk extends ChunkAccess {
if (world instanceof ServerLevel) {
ServerLevel worldserver = (ServerLevel) world;
- return (GameEventListenerRegistry) this.gameEventListenerRegistrySections.computeIfAbsent(ySectionCoord, (j) -> {
- return new EuclideanGameEventListenerRegistry(worldserver, ySectionCoord, this::removeGameEventListenerRegistry);
- });
+ // petal start
+ int sectionIndex = getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord));
+
+ // drop game events that are too far away (32 blocks) from loaded sections
+ // this matches the highest radius of game events in the game
+ if (sectionIndex < 0 || sectionIndex >= this.gameEventListenerRegistrySections.length) {
+ return GameEventListenerRegistry.NOOP;
+ }
+
+ var dispatcher = this.gameEventListenerRegistrySections[sectionIndex];
+
+ if (dispatcher == null) {
+ dispatcher = this.gameEventListenerRegistrySections[sectionIndex] = new EuclideanGameEventListenerRegistry(worldserver, ySectionCoord, this::removeGameEventListenerRegistry);
+ }
+
+ return dispatcher;
+ // petal end
} else {
return super.getListenerRegistry(ySectionCoord);
}
@@ -774,7 +799,7 @@ public class LevelChunk extends ChunkAccess {
}
private void removeGameEventListenerRegistry(int ySectionCoord) {
- this.gameEventListenerRegistrySections.remove(ySectionCoord);
+ this.gameEventListenerRegistrySections[getGameEventSectionIndex(this.getSectionIndexFromSectionY(ySectionCoord))] = null; // petal
}
private void removeBlockEntityTicker(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
index 48132c44ddc147eea0f751c1fc568388730104c5..9307fbf34e7794c1786e08a2045b1356421f554c 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/EuclideanGameEventListenerRegistry.java
@@ -12,8 +12,8 @@ import net.minecraft.world.phys.Vec3;
public class EuclideanGameEventListenerRegistry implements GameEventListenerRegistry {
private final List<GameEventListener> listeners = Lists.newArrayList();
- private final Set<GameEventListener> listenersToRemove = Sets.newHashSet();
- private final List<GameEventListener> listenersToAdd = Lists.newArrayList();
+ //private final Set<GameEventListener> listenersToRemove = Sets.newHashSet(); // petal - not necessary
+ //private final List<GameEventListener> listenersToAdd = Lists.newArrayList(); // petal
private boolean processing;
private final ServerLevel level;
private final int sectionY;
@@ -33,7 +33,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
@Override
public void register(GameEventListener listener) {
if (this.processing) {
- this.listenersToAdd.add(listener);
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
} else {
this.listeners.add(listener);
}
@@ -44,7 +44,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
@Override
public void unregister(GameEventListener listener) {
if (this.processing) {
- this.listenersToRemove.add(listener);
+ throw new java.util.ConcurrentModificationException(); // petal - disallow concurrent modification
} else {
this.listeners.remove(listener);
}
@@ -65,7 +65,7 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
while(iterator.hasNext()) {
GameEventListener gameEventListener = iterator.next();
- if (this.listenersToRemove.remove(gameEventListener)) {
+ if (false) { // petal - disallow concurrent modification
iterator.remove();
} else {
Optional<Vec3> optional = getPostableListenerPosition(this.level, pos, gameEventListener);
@@ -79,6 +79,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
this.processing = false;
}
+ // petal start
+ /*
if (!this.listenersToAdd.isEmpty()) {
this.listeners.addAll(this.listenersToAdd);
this.listenersToAdd.clear();
@@ -88,6 +90,8 @@ public class EuclideanGameEventListenerRegistry implements GameEventListenerRegi
this.listeners.removeAll(this.listenersToRemove);
this.listenersToRemove.clear();
}
+ */
+ // petal end
return bl;
}
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
index f2d10d58617644a589ecec3e17358c1277795e5d..ea7b3485e81cd1cb8158a1811b78691bb19635fd 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
@@ -45,6 +45,7 @@ public class GameEventDispatcher {
int k1 = SectionPos.blockToSectionCoord(blockposition.getZ() + i);
List<GameEvent.ListenerInfo> list = new ArrayList();
GameEventListenerRegistry.ListenerVisitor gameeventlistenerregistry_a = (gameeventlistener, vec3d1) -> {
+ if (!gameeventlistener.listensToEvent(event, emitter)) return; // petal - if they don't listen, ignore
if (gameeventlistener.getDeliveryMode() == GameEventListener.DeliveryMode.BY_DISTANCE) {
list.add(new GameEvent.ListenerInfo(event, emitterPos, emitter, gameeventlistener, vec3d1));
} else {
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
index a4148dd326b10b0eb2bc7884691d79dcda60e010..5859d7af9052a150f5d115bb0e2cbd102374f162 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventListener.java
@@ -22,4 +22,10 @@ public interface GameEventListener {
public interface Holder<T extends GameEventListener> {
T getListener();
}
+
+ // petal start - add check for seeing if this listener cares about an event
+ default boolean listensToEvent(GameEvent gameEvent, GameEvent.Context context) {
+ return true;
+ }
+ // petal end
}

View File

@@ -1,458 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: peaches94 <peachescu94@gmail.com>
Date: Sat, 2 Jul 2022 00:35:56 -0500
Subject: [PATCH] Petal: Multithreaded Tracker
Original code by Bloom-host, licensed under GPL v3
You can find the original code on https://github.com/Bloom-host/Petal
This patch was ported downstream from the Petal fork, and is derived from
the Airplane fork by Paul Sauve
Based off the Airplane multithreaded tracker, this patch properly handles
concurrent accesses everywhere, as well as being much simpler to maintain
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/dev/etil/mirai/tracker/MultithreadedTracker.java b/src/main/java/dev/etil/mirai/tracker/MultithreadedTracker.java
new file mode 100644
index 0000000000000000000000000000000000000000..613bd104762755395e86101decaf1cb7dc74d2ad
--- /dev/null
+++ b/src/main/java/dev/etil/mirai/tracker/MultithreadedTracker.java
@@ -0,0 +1,154 @@
+package dev.etil.mirai.tracker;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet;
+import io.papermc.paper.world.ChunkEntitySlices;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ChunkMap;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.level.chunk.LevelChunk;
+
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MultithreadedTracker {
+
+ private enum TrackerStage {
+ UPDATE_PLAYERS,
+ SEND_CHANGES
+ }
+
+ private static final int parallelism = Math.max(4, Runtime.getRuntime().availableProcessors());
+ private static final Executor trackerExecutor = Executors.newFixedThreadPool(parallelism, new ThreadFactoryBuilder()
+ .setNameFormat("mirai-tracker-%d")
+ .setPriority(Thread.NORM_PRIORITY - 2)
+ .build());
+
+ private final IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks;
+ private final AtomicInteger taskIndex = new AtomicInteger();
+
+ private final ConcurrentLinkedQueue<Runnable> mainThreadTasks;
+ private final AtomicInteger finishedTasks = new AtomicInteger();
+
+ public MultithreadedTracker(IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks, ConcurrentLinkedQueue<Runnable> mainThreadTasks) {
+ this.entityTickingChunks = entityTickingChunks;
+ this.mainThreadTasks = mainThreadTasks;
+ }
+
+ public void tick() {
+ int iterator = this.entityTickingChunks.createRawIterator();
+
+ if (iterator == -1) {
+ return;
+ }
+
+ // start with updating players
+ try {
+ this.taskIndex.set(iterator);
+ this.finishedTasks.set(0);
+
+ for (int i = 0; i < parallelism; i++) {
+ trackerExecutor.execute(this::runUpdatePlayers);
+ }
+
+ while (this.taskIndex.get() < this.entityTickingChunks.getListSize()) {
+ this.runMainThreadTasks();
+ this.handleChunkUpdates(5); // assist
+ }
+
+ while (this.finishedTasks.get() != parallelism) {
+ this.runMainThreadTasks();
+ }
+
+ this.runMainThreadTasks(); // finish any remaining tasks
+ } finally {
+ this.entityTickingChunks.finishRawIterator();
+ }
+
+ // then send changes
+ iterator = this.entityTickingChunks.createRawIterator();
+
+ if (iterator == -1) {
+ return;
+ }
+
+ try {
+ do {
+ LevelChunk chunk = this.entityTickingChunks.rawGet(iterator);
+
+ if (chunk != null) {
+ this.updateChunkEntities(chunk, TrackerStage.SEND_CHANGES);
+ }
+ } while (++iterator < this.entityTickingChunks.getListSize());
+ } finally {
+ this.entityTickingChunks.finishRawIterator();
+ }
+ }
+
+ private void runMainThreadTasks() {
+ try {
+ Runnable task;
+ while ((task = this.mainThreadTasks.poll()) != null) {
+ task.run();
+ }
+ } catch (Throwable throwable) {
+ MinecraftServer.LOGGER.warn("Tasks failed while ticking track queue", throwable);
+ }
+ }
+
+ private void runUpdatePlayers() {
+ try {
+ while (handleChunkUpdates(10));
+ } finally {
+ this.finishedTasks.incrementAndGet();
+ }
+ }
+
+ private boolean handleChunkUpdates(int tasks) {
+ int index;
+ while ((index = this.taskIndex.getAndAdd(tasks)) < this.entityTickingChunks.getListSize()) {
+ for (int i = index; i < index + tasks && i < this.entityTickingChunks.getListSize(); i++) {
+ LevelChunk chunk = this.entityTickingChunks.rawGet(i);
+ if (chunk != null) {
+ try {
+ this.updateChunkEntities(chunk, TrackerStage.UPDATE_PLAYERS);
+ } catch (Throwable throwable) {
+ MinecraftServer.LOGGER.warn("Ticking tracker failed", throwable);
+ }
+
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private void updateChunkEntities(LevelChunk chunk, TrackerStage trackerStage) {
+ final ChunkEntitySlices entitySlices = chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ);
+ if (entitySlices == null) {
+ return;
+ }
+
+ final Entity[] rawEntities = entitySlices.entities.getRawData();
+ final ChunkMap chunkMap = chunk.level.chunkSource.chunkMap;
+
+ for (int i = 0; i < rawEntities.length; i++) {
+ Entity entity = rawEntities[i];
+ if (entity != null) {
+ ChunkMap.TrackedEntity entityTracker = chunkMap.entityMap.get(entity.getId());
+ if (entityTracker != null) {
+ if (trackerStage == TrackerStage.SEND_CHANGES) {
+ entityTracker.serverEntity.sendChanges();
+ } else if (trackerStage == TrackerStage.UPDATE_PLAYERS) {
+ entityTracker.updatePlayers(entityTracker.entity.getPlayersInTrackRange());
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
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 760535e1d6335cf07b6222525610a11318d2596f..2632dade6bfaa185a94e95210a31dc3824b7746f 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -4,6 +4,7 @@ import co.aikar.timings.TimedEventExecutor;
import com.destroystokyo.paper.event.server.ServerExceptionEvent;
import com.destroystokyo.paper.exception.ServerEventException;
import com.google.common.collect.Sets;
+import net.minecraft.server.MinecraftServer;
import org.bukkit.Server;
import org.bukkit.Warning;
import org.bukkit.event.Event;
@@ -43,7 +44,14 @@ class PaperEventManager {
if (isAsync && onPrimaryThread) {
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
} else if (!isAsync && !onPrimaryThread && !this.server.isStopping()) {
- throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
+ // Mirai start
+ if (org.dreeam.leaf.LeafConfig.enableAsyncEntityTracker) {
+ MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ } else {
+ throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
+ }
+ // Mirai end
}
// KTP stop - Optimise spigot event bus
}
diff --git a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
index 0fd814f1d65c111266a2b20f86561839a4cef755..dc06747df171678c8531e1153c5fa9b80b70baed 100644
--- a/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
+++ b/src/main/java/io/papermc/paper/util/maplist/IteratorSafeOrderedReferenceSet.java
@@ -15,7 +15,7 @@ public final class IteratorSafeOrderedReferenceSet<E> {
/* list impl */
protected E[] listElements;
- protected int listSize;
+ protected int listSize; public int getListSize() { return this.listSize; } // Mirai - expose listSize
protected final double maxFragFactor;
diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
index 66721a27cc9a373a12dffb72c4a403473377eff6..2bade6af443a39cd0f680fa6bdb22b13ab4f57a0 100644
--- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
@@ -36,7 +36,7 @@ public final class ChunkEntitySlices {
protected final EntityCollectionBySection allEntities;
protected final EntityCollectionBySection hardCollidingEntities;
protected final Reference2ObjectOpenHashMap<Class<? extends Entity>, EntityCollectionBySection> entitiesByClass;
- protected final EntityList entities = new EntityList();
+ public final EntityList entities = new EntityList();
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 f192057ee342b9f09cc4ead1e605e1677b944ecd..9ff4472edf7ca079c9f3fe4afb8cbe242d7d280d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1261,8 +1261,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
entity.tracker = null; // Paper - We're no longer tracked
}
+ // Mirai start - multithreaded tracker
+ private @Nullable dev.etil.mirai.tracker.MultithreadedTracker multithreadedTracker;
+ private final java.util.concurrent.ConcurrentLinkedQueue<Runnable> trackerMainThreadTasks = new java.util.concurrent.ConcurrentLinkedQueue<>();
+ private boolean tracking = false;
+
+ public void runOnTrackerMainThread(final Runnable runnable) {
+ if (this.tracking) {
+ this.trackerMainThreadTasks.add(runnable);
+ } else {
+ runnable.run();
+ }
+ }
+
// Paper start - optimised tracker
private final void processTrackQueue() {
+ if (org.dreeam.leaf.LeafConfig.enableAsyncEntityTracker) {
+ if (this.multithreadedTracker == null) {
+ this.multithreadedTracker = new dev.etil.mirai.tracker.MultithreadedTracker(this.level.chunkSource.entityTickingChunks, this.trackerMainThreadTasks);
+ }
+
+ this.tracking = true;
+ try {
+ this.multithreadedTracker.tick();
+ } finally {
+ this.tracking = false;
+ }
+ return;
+ }
+ // Mirai end
this.level.timings.tracker1.startTiming();
try {
for (TrackedEntity tracker : this.entityMap.values()) {
@@ -1440,11 +1467,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
public class TrackedEntity {
- public final ServerEntity serverEntity;
- final Entity entity;
+ public final ServerEntity serverEntity; // Mirai -> public
+ public final Entity entity; // Mirai -> public
private final int range;
SectionPos lastSectionPos;
- public final Set<ServerPlayerConnection> seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl
+ public final Set<ServerPlayerConnection> seenBy = it.unimi.dsi.fastutil.objects.ReferenceSets.synchronize(new ReferenceOpenHashSet<>()); // Paper - optimise map impl // Mirai - sync
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
@@ -1456,7 +1483,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper start - use distance map to optimise tracker
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> lastTrackerCandidates;
- final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) {
+ public final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates) { // Mirai -> public
com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> oldTrackerCandidates = this.lastTrackerCandidates;
this.lastTrackerCandidates = newTrackerCandidates;
@@ -1498,14 +1525,11 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void broadcast(Packet<?> packet) {
- Iterator iterator = this.seenBy.iterator();
-
- while (iterator.hasNext()) {
- ServerPlayerConnection serverplayerconnection = (ServerPlayerConnection) iterator.next();
-
+ // Mirai start - avoid NPE
+ for (ServerPlayerConnection serverplayerconnection : this.seenBy.toArray(new ServerPlayerConnection[0])) {
serverplayerconnection.send(packet);
}
-
+ // Mirai end
}
public void broadcastAndSend(Packet<?> packet) {
@@ -1517,18 +1541,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void broadcastRemoved() {
- Iterator iterator = this.seenBy.iterator();
-
- while (iterator.hasNext()) {
- ServerPlayerConnection serverplayerconnection = (ServerPlayerConnection) iterator.next();
-
+ // Miria start - avoid NPE
+ for (ServerPlayerConnection serverplayerconnection : this.seenBy.toArray(new ServerPlayerConnection[0])) { // Mirai - avoid NPE
this.serverEntity.removePairing(serverplayerconnection.getPlayer());
}
-
+ // Mirai end
}
public void removePlayer(ServerPlayer player) {
- org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker clear"); // Spigot // Mirai - we can remove async too
if (this.seenBy.remove(player.connection)) {
this.serverEntity.removePairing(player);
}
@@ -1536,7 +1557,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
}
public void updatePlayer(ServerPlayer player) {
- org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot
+ //org.spigotmc.AsyncCatcher.catchOp("player tracker update"); // Spigot // Mirai - we can update async
if (player != this.entity) {
// Paper start - remove allocation of Vec3D here
// Vec3 vec3d = player.position().subtract(this.entity.position());
diff --git a/src/main/java/net/minecraft/server/level/ServerBossEvent.java b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
index ca42c2642a729b90d22b968af7258f3aee72e14b..c4d6d5be09c788bbc062c50d8547538eb84530b4 100644
--- a/src/main/java/net/minecraft/server/level/ServerBossEvent.java
+++ b/src/main/java/net/minecraft/server/level/ServerBossEvent.java
@@ -13,7 +13,7 @@ import net.minecraft.util.Mth;
import net.minecraft.world.BossEvent;
public class ServerBossEvent extends BossEvent {
- private final Set<ServerPlayer> players = Sets.newHashSet();
+ private final Set<ServerPlayer> players = Sets.newConcurrentHashSet(); // Mirai - players can be removed in async tracking
private final Set<ServerPlayer> unmodifiablePlayers = Collections.unmodifiableSet(this.players);
public boolean visible = true;
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index 00e522a7db9ddfd0602e8423b2793f0bbd727b35..dc37a6cf4f64a950acc1743b71fbc3a425a557b1 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -277,7 +277,11 @@ public class ServerEntity {
public void removePairing(ServerPlayer player) {
this.entity.stopSeenByPlayer(player);
- player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}));
+ // Mirai start - ensure main thread
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ player.connection.send(new ClientboundRemoveEntitiesPacket(new int[]{this.entity.getId()}))
+ );
+ // Mirai end
}
public void addPairing(ServerPlayer player) {
@@ -285,7 +289,7 @@ public class ServerEntity {
Objects.requireNonNull(list);
this.sendPairingData(player, list::add);
- player.connection.send(new ClientboundBundlePacket(list));
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> player.connection.send(new ClientboundBundlePacket(list))); // Mirai - main thread
this.entity.startSeenByPlayer(player);
}
@@ -383,19 +387,29 @@ public class ServerEntity {
if (list != null) {
this.trackedDataValues = datawatcher.getNonDefaultValues();
- this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list));
+ // Mirai start - sync
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() ->
+ this.broadcastAndSend(new ClientboundSetEntityDataPacket(this.entity.getId(), list))
+ );
+ // Mirai end
}
if (this.entity instanceof LivingEntity) {
Set<AttributeInstance> set = ((LivingEntity) this.entity).getAttributes().getDirtyAttributes();
if (!set.isEmpty()) {
+ // Mirai start - sync
+ final var copy = Lists.newArrayList(set);
+ ((ServerLevel) this.entity.level()).chunkSource.chunkMap.runOnTrackerMainThread(() -> {
// CraftBukkit start - Send scaled max health
if (this.entity instanceof ServerPlayer) {
- ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(set, false);
+ ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(copy, false);
}
// CraftBukkit end
- this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), set));
+ this.broadcastAndSend(new ClientboundUpdateAttributesPacket(this.entity.getId(), copy));
+
+ });
+ // Mirai end
}
set.clear();
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index b77a84a5ab85839e37aee24da0f4356be3f478e2..75b53f1f237472f55d883a22cc8289c433b801c0 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -2614,7 +2614,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
@Override
public LevelEntityGetter<Entity> getEntities() {
- org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot
+ // org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot // Mirai
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 4ec2954384a7c99b4f489b1b2a666f93ee69e98f..ea46848a7fd9e2642d8b5e9e4dacac8ab9074ed5 100644
--- a/src/main/java/org/dreeam/leaf/LeafConfig.java
+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java
@@ -201,6 +201,8 @@ public class LeafConfig {
public static boolean asyncPathfinding = false;
public static int asyncPathfindingMaxThreads = 0;
public static int asyncPathfindingKeepalive = 60;
+ public static boolean enableAsyncEntityTracker = false;
+ public static boolean enableAsyncEntityTrackerInitialized;
private static void performance() {
boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning,
"Whether or not asynchronous mob spawning should be enabled.",
@@ -261,6 +263,13 @@ public class LeafConfig {
asyncPathfindingMaxThreads = 0;
else
Bukkit.getLogger().log(Level.INFO, "Using " + asyncPathfindingMaxThreads + " threads for Async Pathfinding");
+ boolean asyncEntityTracker = getBoolean("performance.enable-async-entity-tracker", enableAsyncEntityTracker,
+ "Whether or not async entity tracking should be enabled.",
+ "You may encounter issues with NPCs.");
+ if (!enableAsyncEntityTrackerInitialized) {
+ enableAsyncEntityTrackerInitialized = true;
+ enableAsyncEntityTracker = asyncEntityTracker;
+ }
}
public static boolean jadeProtocol = false;

View File

@@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: rafaelflromao <12960698+rafaelflromao@users.noreply.github.com>
Date: Mon, 12 Jun 2023 06:01:40 +0100
Subject: [PATCH] Petal: Sync event calls on async threads
Original code by Bloom-host, licensed under GPL v3
You can find the original code on https://github.com/Bloom-host/Petal
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 2632dade6bfaa185a94e95210a31dc3824b7746f..9687d4a87112a6ed991935321ef15f32dd116b48 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -45,7 +45,7 @@ class PaperEventManager {
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
} else if (!isAsync && !onPrimaryThread && !this.server.isStopping()) {
// Mirai start
- if (org.dreeam.leaf.LeafConfig.enableAsyncEntityTracker) {
+ if (org.dreeam.leaf.LeafConfig.enableAsyncEntityTracker || org.dreeam.leaf.LeafConfig.enableSyncEventCallsOnAsyncThreads) {
MinecraftServer.getServer().scheduleOnMain(event::callEvent);
return;
} else {
diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java
index ea46848a7fd9e2642d8b5e9e4dacac8ab9074ed5..32980bd223a68e7ac2c953e953434d1fef6e0f9f 100644
--- a/src/main/java/org/dreeam/leaf/LeafConfig.java
+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java
@@ -203,6 +203,8 @@ public class LeafConfig {
public static int asyncPathfindingKeepalive = 60;
public static boolean enableAsyncEntityTracker = false;
public static boolean enableAsyncEntityTrackerInitialized;
+ public static boolean enableSyncEventCallsOnAsyncThreads = true;
+ public static boolean enableSyncEventCallsOnAsyncThreadsInitialized;
private static void performance() {
boolean asyncMobSpawning = getBoolean("performance.enable-async-mob-spawning", enableAsyncMobSpawning,
"Whether or not asynchronous mob spawning should be enabled.",
@@ -270,6 +272,13 @@ public class LeafConfig {
enableAsyncEntityTrackerInitialized = true;
enableAsyncEntityTracker = asyncEntityTracker;
}
+ boolean syncEventCalls = getBoolean("performance.enable-sync-event-calls-on-async-threads", enableSyncEventCallsOnAsyncThreads,
+ "Whether or not sync event calls on async threads should be enabled. (If async entity tracker is enabled, this is enabled.)",
+ "You may encounter issues with plugins.");
+ if (!enableSyncEventCallsOnAsyncThreadsInitialized) {
+ enableSyncEventCallsOnAsyncThreadsInitialized = true;
+ enableSyncEventCallsOnAsyncThreads = syncEventCalls;
+ }
}
public static boolean jadeProtocol = false;

View File

@@ -1,200 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Tue, 5 Sep 2023 03:51:38 -0400
Subject: [PATCH] Use commons-lang3
Plugin incompatible
diff --git a/build.gradle.kts b/build.gradle.kts
index 6efb27e3b86f36aed1dc76e9b95124e557a6894e..1fa65de0bc0cc51876baa86b043bfefd2968e57e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -44,7 +44,7 @@ dependencies {
implementation("org.ow2.asm:asm-commons:9.5") // Paper - ASM event executor generation
testImplementation("org.mockito:mockito-core:5.5.0") // Paper - switch to mockito
implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files
- implementation("commons-lang:commons-lang:2.6")
+ implementation("org.apache.commons:commons-lang3:3.13.0")
implementation("net.fabricmc:mapping-io:0.4.2") // Paper - needed to read mappings for stacktrace deobfuscation
runtimeOnly("org.xerial:sqlite-jdbc:3.43.0.0")
runtimeOnly("com.mysql:mysql-connector-j:8.1.0")
diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
index 61fc65624f7d9a3bfa399a58112efb7f55b31652..5b08d669d348787453bce57a7f439c6ecbae8df0 100644
--- a/src/main/java/co/aikar/timings/TimingsExport.java
+++ b/src/main/java/co/aikar/timings/TimingsExport.java
@@ -29,7 +29,7 @@ import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.minecraft.server.MinecraftServer;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils; // Leaf - Use commons-lang3
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
index 064712e7b27a200b29c72076a82f4f5611fa507f..d4b1f608248bad0ecde768e125ef49c5f481ea78 100644
--- a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
@@ -1,6 +1,6 @@
package com.destroystokyo.paper.entity;
-import org.apache.commons.lang.Validate;
+import org.apache.commons.lang3.Validate; // Leaf - Use commons-lang3
import org.bukkit.Location;
import org.bukkit.craftbukkit.entity.CraftLivingEntity;
import org.bukkit.entity.LivingEntity;
diff --git a/src/main/java/gg/airplane/structs/ItemListWithBitset.java b/src/main/java/gg/airplane/structs/ItemListWithBitset.java
index a45b135af87324c99a9fdd6ba9564255e5beb199..f1b1fcdb36957404042255c212cd0fbb40a55ad2 100644
--- a/src/main/java/gg/airplane/structs/ItemListWithBitset.java
+++ b/src/main/java/gg/airplane/structs/ItemListWithBitset.java
@@ -4,7 +4,7 @@ package gg.airplane.structs;
import net.minecraft.core.NonNullList;
import net.minecraft.world.item.ItemStack;
-import org.apache.commons.lang.Validate;
+import org.apache.commons.lang3.Validate; // Leaf - Use commons-lang3
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
index 1eaa559b177f2dc982865f96dfc7654bcfabc62c..6b0f3029e539892f4a8c2ec9af2324d42fa362b5 100644
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
@@ -33,7 +33,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.phys.Vec3;
-import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils; // Leaf - Use commons-lang3
import com.mojang.authlib.GameProfile;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
@@ -195,7 +195,7 @@ public final class MCUtil {
* @return Stacktrace
*/
public static String stack() {
- return ExceptionUtils.getFullStackTrace(new Throwable());
+ return ExceptionUtils.getStackTrace(new Throwable()); // Leaf - Use commons-lang3
}
/**
@@ -205,8 +205,8 @@ public final class MCUtil {
* @return Stacktrace
*/
public static String stack(String str) {
- return ExceptionUtils.getFullStackTrace(new Throwable(str));
- }
+ return ExceptionUtils.getStackTrace(new Throwable(str));
+ } // Leaf - Use commons-lang3
public static long getCoordinateKey(final BlockPos blockPos) {
return ((long)(blockPos.getZ() >> 4) << 32) | ((blockPos.getX() >> 4) & 0xFFFFFFFFL);
diff --git a/src/main/java/io/papermc/paper/util/ServerEnvironment.java b/src/main/java/io/papermc/paper/util/ServerEnvironment.java
index 148d233f4f5278ff39eacdaa0f4f0e7d73be936a..91eb919fd7465958bdd8cea8e8c18ee3480c0a71 100644
--- a/src/main/java/io/papermc/paper/util/ServerEnvironment.java
+++ b/src/main/java/io/papermc/paper/util/ServerEnvironment.java
@@ -2,7 +2,7 @@ package io.papermc.paper.util;
import com.sun.security.auth.module.NTSystem;
import com.sun.security.auth.module.UnixSystem;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils; // Leaf - Use commons-lang3
import java.io.IOException;
import java.io.InputStream;
diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java
index e54af9ff2a786e919b8261aa27509be942e70261..29e5e752f65d19c55edf8eb9001c6b1457d47550 100644
--- a/src/main/java/net/minecraft/world/food/FoodData.java
+++ b/src/main/java/net/minecraft/world/food/FoodData.java
@@ -27,7 +27,7 @@ public class FoodData {
// CraftBukkit start - added EntityHuman constructor
public FoodData(Player entityhuman) {
- org.apache.commons.lang.Validate.notNull(entityhuman);
+ org.apache.commons.lang3.Validate.notNull(entityhuman); // Leaf - Use commons-lang3
this.entityhuman = entityhuman;
}
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java
index eafba0532920a3162575dbe656e07734605590f5..64a3cae53997c3fe061c486299c6dd1d87ebd395 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCampfire.java
@@ -63,7 +63,7 @@ public class CraftCampfire extends CraftBlockEntityState<CampfireBlockEntity> im
@Override
public boolean stopCooking(int index) {
- org.apache.commons.lang.Validate.isTrue(-1 < index && index < 4, "Slot index must be between 0 (incl) to 3 (incl)");
+ org.apache.commons.lang3.Validate.isTrue(-1 < index && index < 4, "Slot index must be between 0 (incl) to 3 (incl)"); // Leaf - Use commons-lang3
boolean previous = this.isCookingDisabled(index);
getSnapshot().stopCooking[index] = true;
return previous;
@@ -71,7 +71,7 @@ public class CraftCampfire extends CraftBlockEntityState<CampfireBlockEntity> im
@Override
public boolean startCooking(int index) {
- org.apache.commons.lang.Validate.isTrue(-1 < index && index < 4, "Slot index must be between 0 (incl) to 3 (incl)");
+ org.apache.commons.lang3.Validate.isTrue(-1 < index && index < 4, "Slot index must be between 0 (incl) to 3 (incl)"); // Leaf - Use commons-lang3
boolean previous = this.isCookingDisabled(index);
getSnapshot().stopCooking[index] = false;
return previous;
@@ -79,7 +79,7 @@ public class CraftCampfire extends CraftBlockEntityState<CampfireBlockEntity> im
@Override
public boolean isCookingDisabled(int index) {
- org.apache.commons.lang.Validate.isTrue(-1 < index && index < 4, "Slot index must be between 0 (incl) to 3 (incl)");
+ org.apache.commons.lang3.Validate.isTrue(-1 < index && index < 4, "Slot index must be between 0 (incl) to 3 (incl)"); // Leaf - Use commons-lang3
return getSnapshot().stopCooking[index];
}
// Paper end
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
index 492fdc855fe9735b614b6831aa5baaa6b252cfb6..498205a7eb265f56fc47f1f2ee6d0240880547e1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java
@@ -86,7 +86,7 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem
if (location == null) {
this.getHandle().setPodium(null);
} else {
- org.apache.commons.lang.Validate.isTrue(location.getWorld() == null || location.getWorld().equals(getWorld()), "You cannot set a podium in a different world to where the dragon is");
+ org.apache.commons.lang3.Validate.isTrue(location.getWorld() == null || location.getWorld().equals(getWorld()), "You cannot set a podium in a different world to where the dragon is"); // Leaf - Use commons-lang3
this.getHandle().setPodium(io.papermc.paper.util.MCUtil.toBlockPos(location));
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
index 58ea78d3917d2f264515c41f4df2f9ff6f8e4667..89b721088e84f12f3aaf575022055b6e97f28eb9 100644
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
@@ -18,7 +18,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.Util;
import net.minecraft.server.dedicated.DedicatedServer;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils; // Leaf - Use commons-lang3
import org.bukkit.Bukkit;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.craftbukkit.CraftServer;
diff --git a/src/main/java/org/dreeam/leaf/path/NodeEvaluatorCache.java b/src/main/java/org/dreeam/leaf/path/NodeEvaluatorCache.java
index 13e01a9ec678804a6e670c08d8757efea5fa0b8c..f0ff597679bd5dc3b1378188607e4bdfd4caa291 100644
--- a/src/main/java/org/dreeam/leaf/path/NodeEvaluatorCache.java
+++ b/src/main/java/org/dreeam/leaf/path/NodeEvaluatorCache.java
@@ -2,7 +2,7 @@ package org.dreeam.leaf.path;
import net.minecraft.world.level.pathfinder.NodeEvaluator;
-import org.apache.commons.lang.Validate;
+import org.apache.commons.lang3.Validate; // Leaf - Use commons-lang3
import org.jetbrains.annotations.NotNull;
import java.util.Map;
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 2056fc462ab11a86f17c630e868b70eea4f35553..5a1d9daba0db678446e1e8a0d63a9f0c2645cd21 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -16,7 +16,7 @@ import org.purpurmc.purpur.tool.Strippable;
import org.purpurmc.purpur.tool.Tillable;
import org.purpurmc.purpur.tool.Waxable;
import org.purpurmc.purpur.tool.Weatherable;
-import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang3.BooleanUtils; // Leaf - Use commons-lang3
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;

View File

@@ -1,394 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Thu, 6 Apr 2023 20:53:05 -0400
Subject: [PATCH] Carpet-Fixes: Use optimized PoweredRailBlock logic
Original license: MIT
Original project: https://github.com/fxmorin/carpet-fixes
Full Rewrite of the powered rail iteration logic.
This rewrite brings a massive performance boost while keeping the vanilla order. This is achieved by running all the
powered rail logic from a single rail instead of each block iterating separately. Which was not only very
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 0ec427fe0e1f85c07585e1a05269c4c38fc3e9f5..c86278caae67fde06d3dcb6ffcf51f5bd77804a3 100644
--- a/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PoweredRailBlock.java
@@ -1,6 +1,7 @@
package net.minecraft.world.level.block;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
@@ -12,6 +13,8 @@ import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.state.properties.RailShape;
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
+import java.util.HashMap;
+
public class PoweredRailBlock extends BaseRailBlock {
public static final EnumProperty<RailShape> SHAPE = BlockStateProperties.RAIL_SHAPE_STRAIGHT;
@@ -22,7 +25,13 @@ public class PoweredRailBlock extends BaseRailBlock {
this.registerDefaultState((BlockState) ((BlockState) ((BlockState) ((BlockState) this.stateDefinition.any()).setValue(PoweredRailBlock.SHAPE, RailShape.NORTH_SOUTH)).setValue(PoweredRailBlock.POWERED, false)).setValue(PoweredRailBlock.WATERLOGGED, false));
}
- protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) {
+ private static final Direction[] EAST_WEST_DIR = new Direction[]{Direction.WEST, Direction.EAST};
+ private static final Direction[] NORTH_SOUTH_DIR = new Direction[]{Direction.SOUTH, Direction.NORTH};
+
+ private static final int FORCE_PLACE = UPDATE_MOVE_BY_PISTON | UPDATE_KNOWN_SHAPE | UPDATE_CLIENTS;
+ ;
+
+ protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance, HashMap<BlockPos, Boolean> checkedPos) {
if (distance >= world.purpurConfig.railActivationRange) { // Purpur
return false;
} else {
@@ -33,22 +42,22 @@ public class PoweredRailBlock extends BaseRailBlock {
RailShape blockpropertytrackposition = (RailShape) state.getValue(PoweredRailBlock.SHAPE);
// Leaf start - Optimize PoweredRail swtich
- switch (blockpropertytrackposition) {
- case NORTH_SOUTH -> {
+ switch (blockpropertytrackposition.ordinal()) {
+ case 0 -> {
if (flag) {
++l;
} else {
--l;
}
}
- case EAST_WEST -> {
+ case 1 -> {
if (flag) {
--j;
} else {
++j;
}
}
- case ASCENDING_EAST -> {
+ case 2 -> {
if (flag) {
--j;
} else {
@@ -58,7 +67,7 @@ public class PoweredRailBlock extends BaseRailBlock {
}
blockpropertytrackposition = RailShape.EAST_WEST;
}
- case ASCENDING_WEST -> {
+ case 3 -> {
if (flag) {
--j;
++k;
@@ -68,7 +77,7 @@ public class PoweredRailBlock extends BaseRailBlock {
}
blockpropertytrackposition = RailShape.EAST_WEST;
}
- case ASCENDING_NORTH -> {
+ case 4 -> {
if (flag) {
++l;
} else {
@@ -78,7 +87,7 @@ public class PoweredRailBlock extends BaseRailBlock {
}
blockpropertytrackposition = RailShape.NORTH_SOUTH;
}
- case ASCENDING_SOUTH -> {
+ case 5 -> {
if (flag) {
++l;
++k;
@@ -91,19 +100,38 @@ public class PoweredRailBlock extends BaseRailBlock {
}
// Leaf end
- return this.isSameRailWithPower(world, new BlockPos(j, k, l), flag, distance, blockpropertytrackposition) || flag1 && this.isSameRailWithPower(world, new BlockPos(j, k - 1, l), flag, distance, blockpropertytrackposition); // Leaf - Optimize PoweredRail
+ return this.isSameRailWithPower(world, new BlockPos(j, k, l), flag, distance, blockpropertytrackposition, checkedPos) || flag1 && this.isSameRailWithPower(world, new BlockPos(j, k - 1, l), flag, distance, blockpropertytrackposition, checkedPos); // Leaf - Optimize PoweredRail
}
}
- protected boolean isSameRailWithPower(Level world, BlockPos pos, boolean flag, int distance, RailShape shape) {
+ protected boolean isSameRailWithPower(Level world, BlockPos pos, boolean flag, int distance, RailShape shape, HashMap<BlockPos, Boolean> checkedPos) {
BlockState iblockdata = world.getBlockState(pos);
+ boolean speedCheck = checkedPos.containsKey(pos) && checkedPos.get(pos);
- if (!iblockdata.is((Block) this)) {
- return false;
+ if (speedCheck) {
+ return world.hasNeighborSignal(pos) ||
+ this.findPoweredRailSignal(world, pos, iblockdata, flag, distance + 1, checkedPos);
} else {
- RailShape blockpropertytrackposition1 = (RailShape) iblockdata.getValue(PoweredRailBlock.SHAPE);
-
- return (shape != RailShape.EAST_WEST || (blockpropertytrackposition1 != RailShape.NORTH_SOUTH && blockpropertytrackposition1 != RailShape.ASCENDING_NORTH && blockpropertytrackposition1 != RailShape.ASCENDING_SOUTH)) && ((shape != RailShape.NORTH_SOUTH || (blockpropertytrackposition1 != RailShape.EAST_WEST && blockpropertytrackposition1 != RailShape.ASCENDING_EAST && blockpropertytrackposition1 != RailShape.ASCENDING_WEST)) && ((Boolean) iblockdata.getValue(PoweredRailBlock.POWERED) && (world.hasNeighborSignal(pos) || this.findPoweredRailSignal(world, pos, iblockdata, flag, distance + 1)))); // Leaf - Optimize PoweredRail
+ if (iblockdata.is((Block) this)) {
+ RailShape blockpropertytrackposition1 = (RailShape) iblockdata.getValue(PoweredRailBlock.SHAPE);
+ if (shape == RailShape.EAST_WEST && (
+ blockpropertytrackposition1 == RailShape.NORTH_SOUTH ||
+ blockpropertytrackposition1 == RailShape.ASCENDING_NORTH ||
+ blockpropertytrackposition1 == RailShape.ASCENDING_SOUTH
+ ) || shape == RailShape.NORTH_SOUTH && (
+ blockpropertytrackposition1 == RailShape.EAST_WEST ||
+ blockpropertytrackposition1 == RailShape.ASCENDING_EAST ||
+ blockpropertytrackposition1 == RailShape.ASCENDING_WEST
+ )) {
+ return false;
+ } else if ((Boolean) iblockdata.getValue(PoweredRailBlock.POWERED)) {
+ return world.hasNeighborSignal(pos) ||
+ this.findPoweredRailSignal(world, pos, iblockdata, flag, distance + 1, checkedPos);
+ } else {
+ return false;
+ }
+ }
+ return false;
}
}
@@ -120,13 +148,16 @@ public class PoweredRailBlock extends BaseRailBlock {
return;
}
// CraftBukkit end
- world.setBlock(pos, (BlockState) state.setValue(PoweredRailBlock.POWERED, flag1), 3);
- world.updateNeighborsAt(pos.below(), this);
if (((RailShape) state.getValue(PoweredRailBlock.SHAPE)).isAscending()) {
- world.updateNeighborsAt(pos.above(), this);
+ world.setBlock(pos, (BlockState) state.setValue(PoweredRailBlock.POWERED, flag1), 3);
+ world.updateNeighborsAtExceptFromFacing(pos.below(), this, Direction.UP);
+ world.updateNeighborsAtExceptFromFacing(pos.above(), this, Direction.DOWN); //isAscending
+ } else if (flag1) {
+ powerLane(world, pos, state, ((RailShape) state.getValue(PoweredRailBlock.SHAPE)));
+ } else {
+ dePowerLane(world, pos, state, ((RailShape) state.getValue(PoweredRailBlock.SHAPE)));
}
}
-
}
@Override
@@ -258,4 +289,201 @@ public class PoweredRailBlock extends BaseRailBlock {
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(PoweredRailBlock.SHAPE, PoweredRailBlock.POWERED, PoweredRailBlock.WATERLOGGED);
}
+
+ public static void giveShapeUpdate(Level world, BlockState state, BlockPos pos, BlockPos fromPos, Direction direction) {
+ BlockState oldState = world.getBlockState(pos);
+ Block.updateOrDestroy(
+ oldState,
+ oldState.updateShape(direction.getOpposite(), state, world, pos, fromPos),
+ world,
+ pos,
+ Block.UPDATE_CLIENTS & -34,
+ 0
+ );
+ }
+
+ protected boolean findPoweredRailSignal(Level world, BlockPos pos, BlockState state, boolean flag, int distance) {
+ return false;
+ }
+
+ public void powerLane(Level world, BlockPos pos, BlockState state, RailShape railShape) {
+ world.setBlock(pos, (BlockState) state.setValue(PoweredRailBlock.POWERED, true), FORCE_PLACE);
+ HashMap<BlockPos, Boolean> checkedPos = new HashMap<>();
+ checkedPos.put(pos, true);
+ int[] count = new int[2];
+ if (railShape == RailShape.NORTH_SOUTH) { //Order: +z, -z
+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
+ setRailPositionsPower(world, pos, checkedPos, count, i, NORTH_SOUTH_DIR[i]);
+ }
+ updateRails(false, world, pos, state, count);
+ } else if (railShape == RailShape.EAST_WEST) { //Order: -x, +x
+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
+ setRailPositionsPower(world, pos, checkedPos, count, i, EAST_WEST_DIR[i]);
+ }
+ updateRails(true, world, pos, state, count);
+ }
+ }
+
+ public void dePowerLane(Level world, BlockPos pos, BlockState state, RailShape railShape) {
+ world.setBlock(pos, (BlockState) state.setValue(PoweredRailBlock.POWERED, false), FORCE_PLACE);
+ int[] count = new int[2];
+ if (railShape == RailShape.NORTH_SOUTH) { //Order: +z, -z
+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
+ setRailPositionsDePower(world, pos, count, i, NORTH_SOUTH_DIR[i]);
+ }
+ updateRails(false, world, pos, state, count);
+ } else if (railShape == RailShape.EAST_WEST) { //Order: -x, +x
+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
+ setRailPositionsDePower(world, pos, count, i, EAST_WEST_DIR[i]);
+ }
+ updateRails(true, world, pos, state, count);
+ }
+ }
+
+ private void setRailPositionsPower(Level world, BlockPos pos, HashMap<BlockPos, Boolean> checkedPos,
+ int[] count, int i, Direction direction) {
+ for (int z = 1; z < world.purpurConfig.railActivationRange; z++) {
+ BlockPos newPos = pos.relative(direction, z);
+ BlockState state = world.getBlockState(newPos);
+ if (checkedPos.containsKey(newPos)) {
+ if (!checkedPos.get(newPos)) break;
+ count[i]++;
+ } else if (!state.is((Block) this) || state.getValue(PoweredRailBlock.POWERED) || !(
+ world.hasNeighborSignal(newPos) ||
+ this.findPoweredRailSignal(world, newPos, state, true, 0, checkedPos) ||
+ this.findPoweredRailSignal(world, newPos, state, false, 0, checkedPos)
+ )) {
+ checkedPos.put(newPos, false);
+ break;
+ } else {
+ checkedPos.put(newPos, true);
+ world.setBlock(newPos, (BlockState) state.setValue(PoweredRailBlock.POWERED, true), FORCE_PLACE);
+ count[i]++;
+ }
+ }
+ }
+
+ private void setRailPositionsDePower(Level world, BlockPos pos, int[] count, int i, Direction direction) {
+ for (int z = 1; z < world.purpurConfig.railActivationRange; z++) {
+ BlockPos newPos = pos.relative(direction, z);
+ BlockState state = world.getBlockState(newPos);
+ if (!state.is((Block) this) || !state.getValue(PoweredRailBlock.POWERED) || world.hasNeighborSignal(newPos) ||
+ this.findPoweredRailSignal(world, newPos, state, true, 0) ||
+ this.findPoweredRailSignal(world, newPos, state, false, 0)) break;
+ world.setBlock(newPos, (BlockState) state.setValue(PoweredRailBlock.POWERED, false), FORCE_PLACE);
+ count[i]++;
+ }
+ }
+
+ private void shapeUpdateEnd(Level world, BlockPos pos, BlockState state, int endPos,
+ Direction direction, int currentPos, BlockPos blockPos) {
+ if (currentPos == endPos) {
+ BlockPos newPos = pos.relative(direction, currentPos + 1);
+ giveShapeUpdate(world, state, newPos, pos, direction);
+ BlockState iblockdata = world.getBlockState(blockPos);
+ if (iblockdata.is((Block) this) && iblockdata.getValue(PoweredRailBlock.SHAPE).isAscending())
+ giveShapeUpdate(world, state, newPos.above(), pos, direction);
+ }
+ }
+
+ private void neighborUpdateEnd(Level world, BlockPos pos, int endPos, Direction direction,
+ Block block, int currentPos, BlockPos blockPos) {
+ if (currentPos == endPos) {
+ BlockPos newPos = pos.relative(direction, currentPos + 1);
+ world.neighborChanged(newPos, block, pos);
+ BlockState state = world.getBlockState(blockPos);
+ if (state.is((Block) this) && state.getValue(PoweredRailBlock.SHAPE).isAscending())
+ world.neighborChanged(newPos.above(), block, blockPos);
+ }
+ }
+
+ private void updateRailsSectionEastWestShape(Level world, BlockPos pos, int c, BlockState state,
+ Direction dir, int[] count, int countAmt) {
+ BlockPos pos1 = pos.relative(dir, c);
+ if (c == 0 && count[1] == 0)
+ giveShapeUpdate(world, state, pos1.relative(dir.getOpposite()), pos, dir.getOpposite());
+ shapeUpdateEnd(world, pos, state, countAmt, dir, c, pos1);
+ giveShapeUpdate(world, state, pos1.below(), pos, Direction.DOWN);
+ giveShapeUpdate(world, state, pos1.above(), pos, Direction.UP);
+ giveShapeUpdate(world, state, pos1.north(), pos, Direction.NORTH);
+ giveShapeUpdate(world, state, pos1.south(), pos, Direction.SOUTH);
+ }
+
+ private void updateRailsSectionNorthSouthShape(Level world, BlockPos pos, int c, BlockState state,
+ Direction dir, int[] count, int countAmt) {
+ BlockPos pos1 = pos.relative(dir, c);
+ giveShapeUpdate(world, state, pos1.west(), pos, Direction.WEST);
+ giveShapeUpdate(world, state, pos1.east(), pos, Direction.EAST);
+ giveShapeUpdate(world, state, pos1.below(), pos, Direction.DOWN);
+ giveShapeUpdate(world, state, pos1.above(), pos, Direction.UP);
+ shapeUpdateEnd(world, pos, state, countAmt, dir, c, pos1);
+ if (c == 0 && count[1] == 0)
+ giveShapeUpdate(
+ world, state, pos1.relative(dir.getOpposite()), pos, dir.getOpposite()
+ );
+ }
+
+ private void updateRails(boolean eastWest, Level world, BlockPos pos, BlockState state, int[] count) {
+ if (eastWest) {
+ for (int i = 0; i < EAST_WEST_DIR.length; ++i) {
+ int countAmt = count[i];
+ if (i == 1 && countAmt == 0) continue;
+ Direction dir = EAST_WEST_DIR[i];
+ Block block = state.getBlock();
+ for (int c = countAmt; c >= i; c--) {
+ BlockPos p = pos.relative(dir, c);
+ if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, pos);
+ neighborUpdateEnd(world, pos, countAmt, dir, block, c, p);
+ world.neighborChanged(p.below(), block, pos);
+ world.neighborChanged(p.above(), block, pos);
+ world.neighborChanged(p.north(), block, pos);
+ world.neighborChanged(p.south(), block, pos);
+ BlockPos pos2 = pos.relative(dir, c).below();
+ world.neighborChanged(pos2.below(), block, pos);
+ world.neighborChanged(pos2.north(), block, pos);
+ world.neighborChanged(pos2.south(), block, pos);
+ if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, pos);
+ if (c == 0 && count[1] == 0)
+ world.neighborChanged(p.relative(dir.getOpposite()).below(), block, pos);
+ }
+ if (org.dreeam.leaf.LeafConfig.reIntroduceReverseRailUpdateOrder) {
+ for (int c = i; c <= countAmt; c++)
+ updateRailsSectionEastWestShape(world, pos, c, state, dir, count, countAmt);
+ } else {
+ for (int c = countAmt; c >= i; c--)
+ updateRailsSectionEastWestShape(world, pos, c, state, dir, count, countAmt);
+ }
+ }
+ } else {
+ for (int i = 0; i < NORTH_SOUTH_DIR.length; ++i) {
+ int countAmt = count[i];
+ if (i == 1 && countAmt == 0) continue;
+ Direction dir = NORTH_SOUTH_DIR[i];
+ Block block = state.getBlock();
+ for (int c = countAmt; c >= i; c--) {
+ BlockPos p = pos.relative(dir, c);
+ world.neighborChanged(p.west(), block, pos);
+ world.neighborChanged(p.east(), block, pos);
+ world.neighborChanged(p.below(), block, pos);
+ world.neighborChanged(p.above(), block, pos);
+ neighborUpdateEnd(world, pos, countAmt, dir, block, c, p);
+ if (c == 0 && count[1] == 0) world.neighborChanged(p.relative(dir.getOpposite()), block, pos);
+ BlockPos pos2 = pos.relative(dir, c).below();
+ world.neighborChanged(pos2.west(), block, pos);
+ world.neighborChanged(pos2.east(), block, pos);
+ world.neighborChanged(pos2.below(), block, pos);
+ if (c == countAmt) world.neighborChanged(pos.relative(dir, c + 1).below(), block, pos);
+ if (c == 0 && count[1] == 0)
+ world.neighborChanged(p.relative(dir.getOpposite()).below(), block, pos);
+ }
+ if (org.dreeam.leaf.LeafConfig.reIntroduceReverseRailUpdateOrder) {
+ for (int c = i; c <= countAmt; c++)
+ updateRailsSectionNorthSouthShape(world, pos, c, state, dir, count, countAmt);
+ } else {
+ for (int c = countAmt; c >= i; c--)
+ updateRailsSectionNorthSouthShape(world, pos, c, state, dir, count, countAmt);
+ }
+ }
+ }
+ }
}
diff --git a/src/main/java/org/dreeam/leaf/LeafConfig.java b/src/main/java/org/dreeam/leaf/LeafConfig.java
index 11d3ccad179680c46b45e17b4461c5da3d9d5592..a285d391c35bc24250c85f68ac228f2d41456c78 100644
--- a/src/main/java/org/dreeam/leaf/LeafConfig.java
+++ b/src/main/java/org/dreeam/leaf/LeafConfig.java
@@ -203,6 +203,8 @@ public class LeafConfig {
public static boolean enableAsyncEntityTrackerInitialized;
public static boolean enableSyncEventCallsOnAsyncThreads;
public static boolean enableSyncEventCallsOnAsyncThreadsInitialized;
+ public static boolean optimizedPoweredRails = false;
+ public static boolean reIntroduceReverseRailUpdateOrder = false;
private static void performance() {
String sentryEnvironment = System.getenv("SENTRY_DSN");
String sentryConfig = getString("performance.sentry-dsn", sentryDsn, "Sentry DSN for improved error logging, leave blank to disable", "Obtain from https://sentry.io/");
@@ -280,6 +282,8 @@ public class LeafConfig {
enableSyncEventCallsOnAsyncThreadsInitialized = true;
enableSyncEventCallsOnAsyncThreads = syncEventCalls;
}
+ optimizedPoweredRails = getBoolean("performance.optimizedPoweredRails", optimizedPoweredRails);
+ reIntroduceReverseRailUpdateOrder = getBoolean("performance.reIntroduceReverseRailUpdateOrder", reIntroduceReverseRailUpdateOrder);
}
public static boolean jadeProtocol = false;