From aa37aa727ad5809f60da01123525555c2bb20a88 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Sat, 25 May 2024 14:37:44 +0800 Subject: [PATCH] Updated Upstream (Leaf API) --- patches/api/0001-Rebrand.patch | 19 + ...les.patch => 0002-Leaf-config-files.patch} | 0 ...try.patch => 0003-Pufferfish-Sentry.patch} | 12 +- ...es.patch => 0004-Purpur-API-Changes.patch} | 32 +- ...005-Revert-Purpur-Fire-Immunity-API.patch} | 0 ...imings.patch => 0006-Remove-Timings.patch} | 0 ...ies.patch => 0007-Bump-Dependencies.patch} | 4 +- ...llow-unknown-event-thread-execution.patch} | 10 +- ...patch => 0009-KeYi-Player-Skull-API.patch} | 25 +- ...atch => 0010-Slice-Smooth-Teleports.patch} | 6 +- ...nfigurable-LibraryLoader-maven-repos.patch | 41 ++ patches/server/0001-Rebrand.patch | 59 ++- .../server/0009-Purpur-Server-Changes.patch | 43 +- ...educe-work-done-by-game-event-system.patch | 186 ------- .../0033-Petal-Multithreaded-Tracker.patch | 458 ------------------ ...al-Sync-event-calls-on-async-threads.patch | 48 -- .../server/0040-Use-commons-lang3.patch | 200 -------- ...Use-optimized-PoweredRailBlock-logic.patch | 394 --------------- 18 files changed, 149 insertions(+), 1388 deletions(-) create mode 100644 patches/api/0001-Rebrand.patch rename patches/api/{0001-Leaf-config-files.patch => 0002-Leaf-config-files.patch} (100%) rename patches/api/{0002-Pufferfish-Sentry.patch => 0003-Pufferfish-Sentry.patch} (96%) rename patches/api/{0003-Purpur-API-Changes.patch => 0004-Purpur-API-Changes.patch} (98%) rename patches/api/{0004-Revert-Purpur-Fire-Immunity-API.patch => 0005-Revert-Purpur-Fire-Immunity-API.patch} (100%) rename patches/api/{0005-Remove-Timings.patch => 0006-Remove-Timings.patch} (100%) rename patches/api/{0006-Bump-Dependencies.patch => 0007-Bump-Dependencies.patch} (97%) rename patches/api/{0007-KTP-Optimize-Spigot-event-bus.patch => 0008-KTP-Allow-unknown-event-thread-execution.patch} (93%) rename patches/api/{0008-KeYi-Player-Skull-API.patch => 0009-KeYi-Player-Skull-API.patch} (57%) rename patches/api/{0009-Slice-Smooth-Teleports.patch => 0010-Slice-Smooth-Teleports.patch} (85%) create mode 100644 patches/api/0011-Configurable-LibraryLoader-maven-repos.patch delete mode 100644 patches/unapplied/server/0022-Petal-reduce-work-done-by-game-event-system.patch delete mode 100644 patches/unapplied/server/0033-Petal-Multithreaded-Tracker.patch delete mode 100644 patches/unapplied/server/0034-Petal-Sync-event-calls-on-async-threads.patch delete mode 100644 patches/unapplied/server/0040-Use-commons-lang3.patch delete mode 100644 patches/unapplied/server/0044-Carpet-Fixes-Use-optimized-PoweredRailBlock-logic.patch diff --git a/patches/api/0001-Rebrand.patch b/patches/api/0001-Rebrand.patch new file mode 100644 index 00000000..70b9f995 --- /dev/null +++ b/patches/api/0001-Rebrand.patch @@ -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)); diff --git a/patches/api/0001-Leaf-config-files.patch b/patches/api/0002-Leaf-config-files.patch similarity index 100% rename from patches/api/0001-Leaf-config-files.patch rename to patches/api/0002-Leaf-config-files.patch diff --git a/patches/api/0002-Pufferfish-Sentry.patch b/patches/api/0003-Pufferfish-Sentry.patch similarity index 96% rename from patches/api/0002-Pufferfish-Sentry.patch rename to patches/api/0003-Pufferfish-Sentry.patch index 6948697b..0bd028ba 100644 --- a/patches/api/0002-Pufferfish-Sentry.patch +++ b/patches/api/0003-Pufferfish-Sentry.patch @@ -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, ""); + } -+ } catch (Exception e) { ++ } catch (Exception ignored) { + } // We can't really safely log exceptions. + } + return fields; diff --git a/patches/api/0003-Purpur-API-Changes.patch b/patches/api/0004-Purpur-API-Changes.patch similarity index 98% rename from patches/api/0003-Purpur-API-Changes.patch rename to patches/api/0004-Purpur-API-Changes.patch index 325a7816..ca3f22e3 100644 --- a/patches/api/0003-Purpur-API-Changes.patch +++ b/patches/api/0004-Purpur-API-Changes.patch @@ -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("Current: %s%s*", distance == 0 ? "" : distance > 0 ? "" : "", 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 diff --git a/patches/api/0004-Revert-Purpur-Fire-Immunity-API.patch b/patches/api/0005-Revert-Purpur-Fire-Immunity-API.patch similarity index 100% rename from patches/api/0004-Revert-Purpur-Fire-Immunity-API.patch rename to patches/api/0005-Revert-Purpur-Fire-Immunity-API.patch diff --git a/patches/api/0005-Remove-Timings.patch b/patches/api/0006-Remove-Timings.patch similarity index 100% rename from patches/api/0005-Remove-Timings.patch rename to patches/api/0006-Remove-Timings.patch diff --git a/patches/api/0006-Bump-Dependencies.patch b/patches/api/0007-Bump-Dependencies.patch similarity index 97% rename from patches/api/0006-Bump-Dependencies.patch rename to patches/api/0007-Bump-Dependencies.patch index d024189b..2a3d0318 100644 --- a/patches/api/0006-Bump-Dependencies.patch +++ b/patches/api/0007-Bump-Dependencies.patch @@ -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") diff --git a/patches/api/0007-KTP-Optimize-Spigot-event-bus.patch b/patches/api/0008-KTP-Allow-unknown-event-thread-execution.patch similarity index 93% rename from patches/api/0007-KTP-Optimize-Spigot-event-bus.patch rename to patches/api/0008-KTP-Allow-unknown-event-thread-execution.patch index 675b906a..5a4b9351 100644 --- a/patches/api/0007-KTP-Optimize-Spigot-event-bus.patch +++ b/patches/api/0008-KTP-Allow-unknown-event-thread-execution.patch @@ -1,15 +1,15 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Bjarne Koll 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 diff --git a/patches/api/0008-KeYi-Player-Skull-API.patch b/patches/api/0009-KeYi-Player-Skull-API.patch similarity index 57% rename from patches/api/0008-KeYi-Player-Skull-API.patch rename to patches/api/0009-KeYi-Player-Skull-API.patch index f5ceddb4..1780ff4d 100644 --- a/patches/api/0008-KeYi-Player-Skull-API.patch +++ b/patches/api/0009-KeYi-Player-Skull-API.patch @@ -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 getSkullAsynchronously(); -+ // KeYi end ++ // Leaf end - KeYi } diff --git a/patches/api/0009-Slice-Smooth-Teleports.patch b/patches/api/0010-Slice-Smooth-Teleports.patch similarity index 85% rename from patches/api/0009-Slice-Smooth-Teleports.patch rename to patches/api/0010-Slice-Smooth-Teleports.patch index 6cdfc877..9bc79d88 100644 --- a/patches/api/0009-Slice-Smooth-Teleports.patch +++ b/patches/api/0010-Slice-Smooth-Teleports.patch @@ -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 diff --git a/patches/api/0011-Configurable-LibraryLoader-maven-repos.patch b/patches/api/0011-Configurable-LibraryLoader-maven-repos.patch new file mode 100644 index 00000000..4a0eacac --- /dev/null +++ b/patches/api/0011-Configurable-LibraryLoader-maven-repos.patch @@ -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 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 diff --git a/patches/server/0001-Rebrand.patch b/patches/server/0001-Rebrand.patch index 96d88770..6ec9add2 100644 --- a/patches/server/0001-Rebrand.patch +++ b/patches/server/0001-Rebrand.patch @@ -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> 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. diff --git a/patches/server/0009-Purpur-Server-Changes.patch b/patches/server/0009-Purpur-Server-Changes.patch index cd87cb71..58761e60 100644 --- a/patches/server/0009-Purpur-Server-Changes.patch +++ b/patches/server/0009-Purpur-Server-Changes.patch @@ -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; diff --git a/patches/unapplied/server/0022-Petal-reduce-work-done-by-game-event-system.patch b/patches/unapplied/server/0022-Petal-reduce-work-done-by-game-event-system.patch deleted file mode 100644 index abeb55a0..00000000 --- a/patches/unapplied/server/0022-Petal-reduce-work-done-by-game-event-system.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: peaches94 -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 fullStatus; - @Nullable - private LevelChunk.PostLoadProcessor postLoad; -- private final Int2ObjectMap 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 blockTicks; - private final LevelChunkTicks 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 listeners = Lists.newArrayList(); -- private final Set listenersToRemove = Sets.newHashSet(); -- private final List listenersToAdd = Lists.newArrayList(); -+ //private final Set listenersToRemove = Sets.newHashSet(); // petal - not necessary -+ //private final List 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 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 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 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 - } diff --git a/patches/unapplied/server/0033-Petal-Multithreaded-Tracker.patch b/patches/unapplied/server/0033-Petal-Multithreaded-Tracker.patch deleted file mode 100644 index 5214f329..00000000 --- a/patches/unapplied/server/0033-Petal-Multithreaded-Tracker.patch +++ /dev/null @@ -1,458 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: peaches94 -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 entityTickingChunks; -+ private final AtomicInteger taskIndex = new AtomicInteger(); -+ -+ private final ConcurrentLinkedQueue mainThreadTasks; -+ private final AtomicInteger finishedTasks = new AtomicInteger(); -+ -+ public MultithreadedTracker(IteratorSafeOrderedReferenceSet entityTickingChunks, ConcurrentLinkedQueue 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 { - - /* 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, 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 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 seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl -+ public final Set 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 lastTrackerCandidates; - -- final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newTrackerCandidates) { -+ public final void updatePlayers(com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newTrackerCandidates) { // Mirai -> public - com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet 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 players = Sets.newHashSet(); -+ private final Set players = Sets.newConcurrentHashSet(); // Mirai - players can be removed in async tracking - private final Set 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 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 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; diff --git a/patches/unapplied/server/0034-Petal-Sync-event-calls-on-async-threads.patch b/patches/unapplied/server/0034-Petal-Sync-event-calls-on-async-threads.patch deleted file mode 100644 index 1478114d..00000000 --- a/patches/unapplied/server/0034-Petal-Sync-event-calls-on-async-threads.patch +++ /dev/null @@ -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; diff --git a/patches/unapplied/server/0040-Use-commons-lang3.patch b/patches/unapplied/server/0040-Use-commons-lang3.patch deleted file mode 100644 index 12d246dd..00000000 --- a/patches/unapplied/server/0040-Use-commons-lang3.patch +++ /dev/null @@ -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 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 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 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; diff --git a/patches/unapplied/server/0044-Carpet-Fixes-Use-optimized-PoweredRailBlock-logic.patch b/patches/unapplied/server/0044-Carpet-Fixes-Use-optimized-PoweredRailBlock-logic.patch deleted file mode 100644 index 10623ba7..00000000 --- a/patches/unapplied/server/0044-Carpet-Fixes-Use-optimized-PoweredRailBlock-logic.patch +++ /dev/null @@ -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 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 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 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 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 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 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;