diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 809a5ed7..a5d979de 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,7 +23,6 @@ jobs: uses: gradle/actions/setup-gradle@v4 with: add-job-summary: never - generate-job-summary: false cache-read-only: false - name: Setup Git Config run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a75ae17d..8c4d4f26 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,6 @@ jobs: uses: gradle/actions/setup-gradle@v4 with: add-job-summary: never - generate-job-summary: false cache-read-only: false - name: Setup Git Config run: | @@ -34,7 +33,7 @@ jobs: - name: Move Jar run: | prop() { - grep "${1}" gradle.properties | cut -d'=' -f2 | sed 's/\r//' + awk -F= -v key="$1" '$1 == key { val = $2; sub(/[[:space:]]*#.*$/, "", val); gsub(/^[[:space:]]+|[[:space:]]+$/, "", val); print val }' gradle.properties } jarName="leaves-$(prop mcVersion).jar" diff --git a/README.md b/README.md index 4e3136ed..78f0464b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ maven { } dependencies { - compileOnly("org.leavesmc.leaves:leaves-api:1.21.5-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves-api:1.21.8-R0.1-SNAPSHOT") } ``` @@ -40,7 +40,7 @@ Each time you want to update your dependency, you must re-build Leaves. Leaves-Server: ```kotlin dependencies { - compileOnly("org.leavesmc.leaves:leaves:1.21.5-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves:1.21.8-R0.1-SNAPSHOT") } ``` diff --git a/README_cn.md b/README_cn.md index 15f131a8..d7269b4f 100644 --- a/README_cn.md +++ b/README_cn.md @@ -30,7 +30,7 @@ maven { } dependencies { - compileOnly("org.leavesmc.leaves:leaves-api:1.21.5-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves-api:1.21.8-R0.1-SNAPSHOT") } ``` @@ -39,7 +39,7 @@ dependencies { Leaves-Server: ```kotlin dependencies { - compileOnly("org.leavesmc.leaves:leaves:1.21.5-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves:1.21.8-R0.1-SNAPSHOT") } ``` diff --git a/build.gradle.kts b/build.gradle.kts index 19c11a2e..797981d2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,7 +18,6 @@ subprojects { } repositories { - mavenLocal() mavenCentral() maven("https://repo.papermc.io/repository/maven-public/") maven("https://repo.leavesmc.org/releases") { @@ -251,6 +250,7 @@ tasks.register("applyNextPatch") { if (failedIndex >= 0) { val directory = project.projectDir.resolve(patchDir[failedIndex]) + executeCommand(listOf("git", "add", "."), directory) val gitCommand = if (hasGitChanges(directory)) { listOf("git", "am", "--continue") diff --git a/gradle.properties b/gradle.properties index 554b95ac..f185d348 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,10 @@ group=org.leavesmc.leaves -version=1.21.5-R0.1-SNAPSHOT -mcVersion=1.21.5 -paperRef=2ba1675c7506cadd8a540ea452e5dafb79ae8947 +version=1.21.8-R0.1-SNAPSHOT +mcVersion=1.21.8 +paperRef=c8a8c0ef8910c809913a00e2d9bdffaec51ff1f4 + preVersion=true org.gradle.caching=true org.gradle.parallel=true + +paper.runDisableWatchdog=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b95..1b33c55b 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 18362b78..ff23a68d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index f5feea6d..23d15a93 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a218..db3a6ac2 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/leaves-api/build.gradle.kts.patch b/leaves-api/build.gradle.kts.patch index 99e53e17..867175e7 100644 --- a/leaves-api/build.gradle.kts.patch +++ b/leaves-api/build.gradle.kts.patch @@ -54,7 +54,7 @@ into("META-INF/maven/${project.group}/${project.name}") @@ -166,7 +_,7 @@ - tasks.withType { + tasks.withType().configureEach { val options = options as StandardJavadocDocletOptions - options.overview = "src/main/javadoc/overview.html" + options.overview = "../paper-api/src/main/javadoc/overview.html" // Leaves - build change diff --git a/leaves-api/paper-patches/features/0001-Delete-Timings.patch b/leaves-api/paper-patches/features/0001-Delete-Timings.patch index 4adb90ae..663897de 100644 --- a/leaves-api/paper-patches/features/0001-Delete-Timings.patch +++ b/leaves-api/paper-patches/features/0001-Delete-Timings.patch @@ -2904,18 +2904,18 @@ index 59fada9b1eb78238d280c6bbb711f52facba52c6..eb4d78c6111a530d015a0b91d14c40ad return i >= j && i <= k; } diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java -index 4acda947b7d69ab4133b4cc94e76d945e4d148d5..d356f1895e8f3fae14bbbe1f60e589af3856b9ec 100644 +index ad1330d87223dfcf3c9da40aa5ece8c21141f0d6..f561ac4ebd8d40266ae9f066e79045bb93113a53 100644 --- a/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java -@@ -32,7 +32,6 @@ public class SimpleCommandMap implements CommandMap { - - private void setDefaultCommands() { - register("bukkit", new ReloadCommand("reload")); +@@ -34,7 +34,6 @@ public class SimpleCommandMap implements CommandMap { + final ReloadCommand reload = new ReloadCommand("reload"); + this.knownCommands.put("bukkit:reload", reload); + this.knownCommands.put("bukkit:rl", reload); - register("bukkit", new co.aikar.timings.TimingsCommand("timings")); } public void setFallbackCommands() { -@@ -64,7 +63,6 @@ public class SimpleCommandMap implements CommandMap { +@@ -66,7 +65,6 @@ public class SimpleCommandMap implements CommandMap { */ @Override public boolean register(@NotNull String label, @NotNull String fallbackPrefix, @NotNull Command command) { @@ -2923,7 +2923,7 @@ index 4acda947b7d69ab4133b4cc94e76d945e4d148d5..d356f1895e8f3fae14bbbe1f60e589af label = label.toLowerCase(Locale.ROOT).trim(); fallbackPrefix = fallbackPrefix.toLowerCase(Locale.ROOT).trim(); boolean registered = register(label, command, false, fallbackPrefix); -@@ -146,17 +144,9 @@ public class SimpleCommandMap implements CommandMap { +@@ -148,17 +146,9 @@ public class SimpleCommandMap implements CommandMap { return false; } @@ -2942,7 +2942,7 @@ index 4acda947b7d69ab4133b4cc94e76d945e4d148d5..d356f1895e8f3fae14bbbe1f60e589af server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper //target.timings.stopTiming(); // Spigot // Paper diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 001465eedafa51ac027a4db51cba6223edfe1171..dd98b4886d21ac92d9f9139450258754e985fb85 100644 +index dfc2d76403993640e6283f25f9f3647bb6d1a30c..cc2a208b7cb118134ca4088c622644b5d2fac1c0 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -720,7 +720,6 @@ public final class SimplePluginManager implements PluginManager { diff --git a/leaves-api/paper-patches/features/0003-Add-fakeplayer-api.patch b/leaves-api/paper-patches/features/0003-Add-fakeplayer-api.patch index c99fba4b..40d5d1d3 100644 --- a/leaves-api/paper-patches/features/0003-Add-fakeplayer-api.patch +++ b/leaves-api/paper-patches/features/0003-Add-fakeplayer-api.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add fakeplayer api diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index c9ea6559f809a6732588b8908001807be3d91196..fe30de1f0a7fc7112466b6eb2e5813f39259c3b6 100644 +index 3bde4ad79ade5aae18e9073307f637717e8dd9e3..9971ed1347f0f37800911c6cd9d0f8ae1a4f100c 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -3007,4 +3007,15 @@ public final class Bukkit { +@@ -3016,4 +3016,15 @@ public final class Bukkit { public static void restart() { server.restart(); } @@ -19,16 +19,16 @@ index c9ea6559f809a6732588b8908001807be3d91196..fe30de1f0a7fc7112466b6eb2e5813f3 + * + * @return Bot Manager + */ -+ public static @NotNull org.leavesmc.leaves.entity.BotManager getBotManager() { ++ public static @NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager() { + return server.getBotManager(); + } + // Leaves end - Bot API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index ed899c4cb4b5261ceff56bbc9ca806e20904508e..a5370832380e93cf029588caeb8e29e03cc52db8 100644 +index 9bab00ab10c78908090c8a1a12d4c84e9324b08b..3e7aad4ddf573f7c868b7824c4f0f34fa08cb1fe 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2716,4 +2716,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2723,4 +2723,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ void allowPausing(@NotNull org.bukkit.plugin.Plugin plugin, boolean value); // Paper end - API to check if the server is sleeping @@ -39,6 +39,6 @@ index ed899c4cb4b5261ceff56bbc9ca806e20904508e..a5370832380e93cf029588caeb8e29e0 + * + * @return Bot Manager + */ -+ @NotNull org.leavesmc.leaves.entity.BotManager getBotManager(); ++ @NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager(); + // Leaves end - Bot API } diff --git a/leaves-api/paper-patches/features/0004-Replay-Mod-API.patch b/leaves-api/paper-patches/features/0004-Replay-Mod-API.patch index dd7ce446..c19bfac3 100644 --- a/leaves-api/paper-patches/features/0004-Replay-Mod-API.patch +++ b/leaves-api/paper-patches/features/0004-Replay-Mod-API.patch @@ -5,30 +5,30 @@ Subject: [PATCH] Replay Mod API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index fe30de1f0a7fc7112466b6eb2e5813f39259c3b6..23f3ab31bbc9d197f9a82f4ed5003e6de814fad7 100644 +index 9971ed1347f0f37800911c6cd9d0f8ae1a4f100c..803611b793daed2d51ef6ab34d01fc8b0a3ecd23 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -3018,4 +3018,10 @@ public final class Bukkit { +@@ -3027,4 +3027,10 @@ public final class Bukkit { return server.getBotManager(); } // Leaves end - Bot API + + // Leaves start - Photographer API -+ public static @NotNull org.leavesmc.leaves.entity.PhotographerManager getPhotographerManager() { ++ public static @NotNull org.leavesmc.leaves.entity.photographer.PhotographerManager getPhotographerManager() { + return server.getPhotographerManager(); + } + // Leaves end - Photographer API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index a5370832380e93cf029588caeb8e29e03cc52db8..2531e82464e54e0c1b707e7c5a62ff0fd5ed8637 100644 +index 3e7aad4ddf573f7c868b7824c4f0f34fa08cb1fe..ce128dd8120b75884cb208d7ba7d316ee110333b 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2725,4 +2725,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2732,4 +2732,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ - @NotNull org.leavesmc.leaves.entity.BotManager getBotManager(); + @NotNull org.leavesmc.leaves.entity.bot.BotManager getBotManager(); // Leaves end - Bot API + + // Leaves start - Photographer API -+ @NotNull org.leavesmc.leaves.entity.PhotographerManager getPhotographerManager(); ++ @NotNull org.leavesmc.leaves.entity.photographer.PhotographerManager getPhotographerManager(); + // Leaves end - Photographer API } diff --git a/leaves-api/paper-patches/features/0005-Bytebuf-API.patch b/leaves-api/paper-patches/features/0005-Bytebuf-API.patch index a08920f1..54357505 100644 --- a/leaves-api/paper-patches/features/0005-Bytebuf-API.patch +++ b/leaves-api/paper-patches/features/0005-Bytebuf-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bytebuf API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 23f3ab31bbc9d197f9a82f4ed5003e6de814fad7..30488f80b98d1dba485e53601edb5cb0e23b7591 100644 +index 803611b793daed2d51ef6ab34d01fc8b0a3ecd23..0149af5bd4234f925e12d78251766be5a16e5060 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -3024,4 +3024,10 @@ public final class Bukkit { +@@ -3033,4 +3033,10 @@ public final class Bukkit { return server.getPhotographerManager(); } // Leaves end - Photographer API @@ -20,12 +20,12 @@ index 23f3ab31bbc9d197f9a82f4ed5003e6de814fad7..30488f80b98d1dba485e53601edb5cb0 + // Leaves end - Bytebuf API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 2531e82464e54e0c1b707e7c5a62ff0fd5ed8637..a1742e64232c949dc88deb5d6083c4bf62e6aae9 100644 +index ce128dd8120b75884cb208d7ba7d316ee110333b..e63fb4e0c55929f2721e16f69e0c0a4b455477fa 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2729,4 +2729,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2736,4 +2736,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Leaves start - Photographer API - @NotNull org.leavesmc.leaves.entity.PhotographerManager getPhotographerManager(); + @NotNull org.leavesmc.leaves.entity.photographer.PhotographerManager getPhotographerManager(); // Leaves end - Photographer API + + // Leaves start - Bytebuf API @@ -33,10 +33,10 @@ index 2531e82464e54e0c1b707e7c5a62ff0fd5ed8637..a1742e64232c949dc88deb5d6083c4bf + // Leaves end - Bytebuf API } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index d34419693fc78b3f7e8f6bbf115f17f29e5e3377..ab45edbc10398d92ddfcfd16d12d49f5b4e87c4c 100644 +index 3584ca0a89f59e391ab6d5be8f2274a6801d025f..4171ac88c491c071af9def920084292e108587f0 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3860,6 +3860,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3859,6 +3859,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM boolean isChunkSent(long chunkKey); // Paper end diff --git a/leaves-api/paper-patches/features/0008-Leaves-Config-API.patch b/leaves-api/paper-patches/features/0008-Leaves-Config-API.patch index d1ad59e6..f3781937 100644 --- a/leaves-api/paper-patches/features/0008-Leaves-Config-API.patch +++ b/leaves-api/paper-patches/features/0008-Leaves-Config-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Config API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 30488f80b98d1dba485e53601edb5cb0e23b7591..91fa30c1713795007faef73280713a33d2518487 100644 +index 0149af5bd4234f925e12d78251766be5a16e5060..3c019280bc751e0710f1d34478b56986bc6000fc 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -3030,4 +3030,10 @@ public final class Bukkit { +@@ -3039,4 +3039,10 @@ public final class Bukkit { return server.getBytebufManager(); } // Leaves end - Bytebuf API @@ -20,10 +20,10 @@ index 30488f80b98d1dba485e53601edb5cb0e23b7591..91fa30c1713795007faef73280713a33 + // Leaves end - Config API } diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index a1742e64232c949dc88deb5d6083c4bf62e6aae9..75a1917d998bf8aa0b86a67ca0f0836804fad012 100644 +index e63fb4e0c55929f2721e16f69e0c0a4b455477fa..37ff5eabaf0fd3ab72eb37a1f21904b5a1adebe0 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2733,4 +2733,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2740,4 +2740,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Leaves start - Bytebuf API org.leavesmc.leaves.bytebuf.BytebufManager getBytebufManager(); // Leaves end - Bytebuf API diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/.editorconfig b/leaves-api/src/main/java/org/leavesmc/leaves/.editorconfig new file mode 100644 index 00000000..9e663b78 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/.editorconfig @@ -0,0 +1,6 @@ +[*.java] +ij_java_if_brace_force = always +ij_java_do_while_brace_force = always +ij_java_for_brace_force = always +ij_java_while_brace_force = always +ij_java_use_fq_class_names = false \ No newline at end of file diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java b/leaves-api/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java index a0c28ae8..63f95dfb 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java @@ -140,6 +140,8 @@ public enum PacketType { ServerboundMoveVehicle, ServerboundPaddleBoat, ServerboundPickItem, + ServerboundPickItemFromBlock, + ServerboundPickItemFromEntity, ServerboundPlaceRecipe, ServerboundPlayerAbilities, ServerboundPlayerAction, @@ -188,5 +190,7 @@ public enum PacketType { ServerboundPong, ServerboundResourcePack, ServerboundPingRequest, - ClientboundPongResponse + ClientboundPongResponse, + ClientboundShowDialog, + ClientboundClearDialog } diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/Bot.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java similarity index 81% rename from leaves-api/src/main/java/org/leavesmc/leaves/entity/Bot.java rename to leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java index 1c8f7371..df7dbdd0 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/Bot.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/Bot.java @@ -1,9 +1,9 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.bot; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.botaction.LeavesBotAction; +import org.leavesmc.leaves.entity.bot.action.BotAction; import java.util.UUID; @@ -38,8 +38,7 @@ public interface Bot extends Player { * * @param action bot action */ - @org.jetbrains.annotations.ApiStatus.Experimental - void addAction(@NotNull LeavesBotAction action); + > void addAction(@NotNull T action); /** * Get the copy action in giving index @@ -47,8 +46,7 @@ public interface Bot extends Player { * @param index index of actions * @return Action of that index */ - @org.jetbrains.annotations.ApiStatus.Experimental - LeavesBotAction getAction(int index); + BotAction getAction(int index); /** * Get action size diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/BotCreator.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotCreator.java similarity index 96% rename from leaves-api/src/main/java/org/leavesmc/leaves/entity/BotCreator.java rename to leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotCreator.java index 65df4ec5..e70b1f33 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/BotCreator.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotCreator.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.bot; import org.bukkit.Bukkit; import org.bukkit.Location; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/BotManager.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java similarity index 62% rename from leaves-api/src/main/java/org/leavesmc/leaves/entity/BotManager.java rename to leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java index 671e53f1..c434364f 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/BotManager.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/BotManager.java @@ -1,9 +1,9 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.bot; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.botaction.CustomBotAction; +import org.leavesmc.leaves.entity.bot.action.BotAction; import java.util.Collection; import java.util.UUID; @@ -37,23 +37,12 @@ public interface BotManager { Collection getBots(); /** - * Register a custom bot action. + * Create a bot action by class. * - * @param name action name - * @param action action executor - * @return true if success, or false + * @param type action class + * @return a bot action instance if one was found, null otherwise */ - @org.jetbrains.annotations.ApiStatus.Experimental - boolean registerCustomBotAction(String name, CustomBotAction action); - - /** - * Unregister a custom bot action. - * - * @param name action name - * @return true if success, or false - */ - @org.jetbrains.annotations.ApiStatus.Experimental - boolean unregisterCustomBotAction(String name); + > T newAction(@NotNull Class type); BotCreator botCreator(@NotNull String realName, @NotNull Location location); } diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/AttackAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/AttackAction.java new file mode 100644 index 00000000..9b773f73 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/AttackAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to attack entities. + */ +public interface AttackAction extends TimerBotAction { + static AttackAction create() { + return Bukkit.getBotManager().newAction(AttackAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/BotAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/BotAction.java new file mode 100644 index 00000000..8e645119 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/BotAction.java @@ -0,0 +1,85 @@ +package org.leavesmc.leaves.entity.bot.action; + +import java.util.UUID; +import java.util.function.Consumer; + +/** + * Represents an action that can be performed by a Bot. + *

+ * This interface defines the basic properties of an action (such as name and UUID) + * and lifecycle event callbacks (success, failure, stop). + * + * @param the type of the callback parameter, usually a context object related to the action + */ +public interface BotAction { + + /** + * Gets the name of this action. + * + * @return the action name + */ + String getName(); + + /** + * Gets the UUID of this action. + * + * @return the UUID of the action + */ + UUID getUUID(); + + /** + * Sets whether this action is cancelled. + * + * @param cancel true to cancel the action, false otherwise + */ + void setCancelled(boolean cancel); + + /** + * Checks whether this action has been cancelled. + * + * @return true if cancelled, false otherwise + */ + boolean isCancelled(); + + /** + * Sets the callback to be executed when the action fails. + * + * @param onFail the callback to execute on failure, with a parameter of type T + */ + void setOnFail(Consumer onFail); + + /** + * Gets the callback to be executed when the action fails. + * + * @return the failure callback + */ + Consumer getOnFail(); + + /** + * Sets the callback to be executed when the action succeeds. + * + * @param onSuccess the callback to execute on success, with a parameter of type T + */ + void setOnSuccess(Consumer onSuccess); + + /** + * Gets the callback to be executed when the action succeeds. + * + * @return the success callback + */ + Consumer getOnSuccess(); + + /** + * Sets the callback to be executed when the action is stopped. + * + * @param onStop the callback to execute on stop, with a parameter of type T + */ + void setOnStop(Consumer onStop); + + /** + * Gets the callback to be executed when the action is stopped. + * + * @return the stop callback + */ + Consumer getOnStop(); +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/BreakBlockAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/BreakBlockAction.java new file mode 100644 index 00000000..a314fd17 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/BreakBlockAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to break a block. + */ +public interface BreakBlockAction extends TimerBotAction { + static BreakBlockAction create() { + return Bukkit.getBotManager().newAction(BreakBlockAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/DropAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/DropAction.java new file mode 100644 index 00000000..606ebadc --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/DropAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to drop all items in its inventory. + */ +public interface DropAction extends TimerBotAction { + static DropAction create() { + return Bukkit.getBotManager().newAction(DropAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/FishAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/FishAction.java new file mode 100644 index 00000000..2fc985c6 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/FishAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to perform auto fishing. + */ +public interface FishAction extends TimerBotAction { + static FishAction create() { + return Bukkit.getBotManager().newAction(FishAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/JumpAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/JumpAction.java new file mode 100644 index 00000000..5daf5fcf --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/JumpAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to perform a jump. + */ +public interface JumpAction extends TimerBotAction { + static JumpAction create() { + return Bukkit.getBotManager().newAction(JumpAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/LookAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/LookAction.java new file mode 100644 index 00000000..ea0db1d7 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/LookAction.java @@ -0,0 +1,54 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +/** + * Represents an action for a bot to look at a specific position or player. + *

+ * If both a position and a player are set, the player target takes precedence. + */ +public interface LookAction extends BotAction { + + /** + * Sets the position in the world for the bot to look at. + *

+ * If a player target is set via {@link #setTarget(Player)}, the bot will look at the player instead of this position. + * + * @param pos the {@link Vector} representing the position to look at + * @return this {@code LookAction} instance for method chaining + */ + LookAction setPos(Vector pos); + + /** + * Gets the position in the world that the bot is set to look at. + *

+ * If a player target is set, this value may be ignored. + * + * @return the {@link Vector} position to look at, or {@code null} if not set + */ + Vector getPos(); + + /** + * Sets the player for the bot to look at. + *

+ * When a player is set as the target, the bot will continuously look at the player's current position, + * overriding any position set by {@link #setPos(Vector)}. + * + * @param player the {@link Player} to look at, or {@code null} to clear the target + * @return this {@code LookAction} instance for method chaining + */ + LookAction setTarget(Player player); + + /** + * Gets the player that the bot is set to look at. + * + * @return the {@link Player} target, or {@code null} if not set + */ + Player getTarget(); + + static LookAction create() { + return Bukkit.getBotManager().newAction(LookAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/MoveAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/MoveAction.java new file mode 100644 index 00000000..eb855bb9 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/MoveAction.java @@ -0,0 +1,44 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to move to a specific direction. + */ +public interface MoveAction extends StateBotAction { + + /** + * Gets the direction of the move action. + * + * @return the direction of the move action + */ + MoveDirection getDirection(); + + /** + * Sets the direction of the move action. + * + * @param direction the direction to set + * @return this action instance + */ + MoveAction setDirection(MoveDirection direction); + + /** + * Represents possible movement directions for the bot. + */ + enum MoveDirection { + FORWARD("forward"), + BACKWARD("backward"), + LEFT("left"), + RIGHT("right"); + + public final String name; + + MoveDirection(String name) { + this.name = name; + } + } + + static MoveAction create() { + return Bukkit.getBotManager().newAction(MoveAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/RotationAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/RotationAction.java new file mode 100644 index 00000000..9fb75444 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/RotationAction.java @@ -0,0 +1,43 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to rotate to a specific yaw and pitch. + */ +public interface RotationAction extends BotAction { + + /** + * Sets the yaw of the rotation. + * + * @param yaw the yaw to set + * @return this action instance + */ + RotationAction setYaw(float yaw); + + /** + * Sets the pitch of the rotation. + * + * @param pitch the pitch to set + * @return this action instance + */ + RotationAction setPitch(float pitch); + + /** + * Gets the yaw of the rotation. + * + * @return the yaw + */ + float getYaw(); + + /** + * Gets the pitch of the rotation. + * + * @return the pitch + */ + float getPitch(); + + static RotationAction create() { + return Bukkit.getBotManager().newAction(RotationAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/SneakAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/SneakAction.java new file mode 100644 index 00000000..23c68e6e --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/SneakAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to sneak. + */ +public interface SneakAction extends StateBotAction { + static SneakAction create() { + return Bukkit.getBotManager().newAction(SneakAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/StateBotAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/StateBotAction.java new file mode 100644 index 00000000..7199f343 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/StateBotAction.java @@ -0,0 +1,10 @@ +package org.leavesmc.leaves.entity.bot.action; + +/** + * Represents a type of bot action that places the bot in a specific state while the action is active. + * When the action is stopped, the associated state is removed from the bot. + * + * @param The type of entity that this action operates on. + */ +public interface StateBotAction extends BotAction { +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/SwimAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/SwimAction.java new file mode 100644 index 00000000..6fa03c67 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/SwimAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action for a bot to float up in water. + */ +public interface SwimAction extends StateBotAction { + static SwimAction create() { + return Bukkit.getBotManager().newAction(SwimAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/TimerBotAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/TimerBotAction.java new file mode 100644 index 00000000..c75129fe --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/TimerBotAction.java @@ -0,0 +1,68 @@ +package org.leavesmc.leaves.entity.bot.action; + +/** + * Represents a scheduled bot task that runs periodically. + *

+ * TimerBotAction allows configuration of start delay, execution interval, and the number of executions. + * It is intended for bot actions that need to be triggered at regular intervals. + * + * @param the type of entity this action operates on + */ +public interface TimerBotAction extends BotAction { + + /** + * Sets the delay in ticks before the task starts for the first time. + * + * @param delayTick the number of ticks to delay before the first execution + */ + void setStartDelayTick(int delayTick); + + /** + * Gets the delay in ticks before the task starts for the first time. + * + * @return the number of ticks to delay before the first execution + */ + int getStartDelayTick(); + + /** + * Sets the interval in ticks between each execution of the task. + * + * @param intervalTick the number of ticks between executions + */ + void setDoIntervalTick(int intervalTick); + + /** + * Gets the interval in ticks between each execution of the task. + * + * @return the number of ticks between executions + */ + int getDoIntervalTick(); + + /** + * Sets the total number of times the task should be executed. + * + * @param doNumber the total number of executions + */ + void setDoNumber(int doNumber); + + /** + * Gets the total number of times the task should be executed. + * + * @return the total number of executions + */ + int getDoNumber(); + + /** + * Gets the number of ticks remaining until the next execution. + * + * @return the number of ticks until the next execution + */ + int getTickToNext(); + + /** + * Gets the number of executions remaining for this task. + * + * @return the number of executions remaining + */ + int getDoNumberRemaining(); +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemAction.java new file mode 100644 index 00000000..7114a04a --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot only uses an item, without using it on blocks or entities. + */ +public interface UseItemAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemAction setUseTick(int useTick); + + static UseItemAction create() { + return Bukkit.getBotManager().newAction(UseItemAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemAutoAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemAutoAction.java new file mode 100644 index 00000000..feb6d163 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemAutoAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot uses an item, fully simulating the effect of a player right-clicking. + */ +public interface UseItemAutoAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemAutoAction setUseTick(int useTick); + + static UseItemAutoAction create() { + return Bukkit.getBotManager().newAction(UseItemAutoAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOffhandAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOffhandAction.java new file mode 100644 index 00000000..a96b1833 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOffhandAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot only uses the item in its offhand, without using it on blocks or entities. + */ +public interface UseItemOffhandAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemOffhandAction setUseTick(int useTick); + + static UseItemOffhandAction create() { + return Bukkit.getBotManager().newAction(UseItemOffhandAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOnAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOnAction.java new file mode 100644 index 00000000..166c7a35 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOnAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot uses an item on a block. + */ +public interface UseItemOnAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemOnAction setUseTick(int useTick); + + static UseItemOnAction create() { + return Bukkit.getBotManager().newAction(UseItemOnAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOnOffhandAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOnOffhandAction.java new file mode 100644 index 00000000..663e99d6 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemOnOffhandAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot uses an item in its offhand on a block. + */ +public interface UseItemOnOffhandAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemOnOffhandAction setUseTick(int useTick); + + static UseItemOnOffhandAction create() { + return Bukkit.getBotManager().newAction(UseItemOnOffhandAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemToAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemToAction.java new file mode 100644 index 00000000..afa143a4 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemToAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot uses an item to an entity. + */ +public interface UseItemToAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemToAction setUseTick(int useTick); + + static UseItemToAction create() { + return Bukkit.getBotManager().newAction(UseItemToAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemToOffhandAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemToOffhandAction.java new file mode 100644 index 00000000..8cb10781 --- /dev/null +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/bot/action/UseItemToOffhandAction.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.entity.bot.action; + +import org.bukkit.Bukkit; + +/** + * Represents an action where a bot uses an item in its offhand to an entity. + */ +public interface UseItemToOffhandAction extends TimerBotAction { + + /** + * Gets the equivalent right-click hold duration in ticks. + * Default is -1, which means will not be released. + * + * @return the equivalent right-click hold duration + */ + int getUseTick(); + + /** + * Sets the equivalent right-click hold duration in ticks. + * + * @param useTick the equivalent right-click hold duration + * @return this action instance + */ + UseItemToOffhandAction setUseTick(int useTick); + + static UseItemToOffhandAction create() { + return Bukkit.getBotManager().newAction(UseItemToOffhandAction.class); + } +} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/BotActionType.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/BotActionType.java deleted file mode 100644 index 8a849c8a..00000000 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/BotActionType.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.leavesmc.leaves.entity.botaction; - -/** - * A Leaves bot action enum - */ - -@org.jetbrains.annotations.ApiStatus.Experimental -public enum BotActionType { - ATTACK("attack"), - BREAK("break"), - DROP("drop"), - FISH("fish"), - JUMP("jump"), - LOOK("look"), - ROTATE("rotate"), - ROTATION("rotation"), - SNEAK("sneak"), - SWIM("swim"), - USE("use"), - USE_ON("use_on"), - USE_TO("use_to"), - USE_OFFHAND("use_offhand"), - USE_ON_OFFHAND("use_on_offhand"), - USE_TO_OFFHAND("use_to_offhand"); - - private final String name; - - BotActionType(String name) { - this.name = name; - } - - public String getName() { - return name; - } -} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/CustomBotAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/CustomBotAction.java deleted file mode 100644 index 88a57edb..00000000 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/CustomBotAction.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.leavesmc.leaves.entity.botaction; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; - -import java.util.List; - -/** - * Represents a class which contains methods for a custom bot action - */ -@org.jetbrains.annotations.ApiStatus.Experimental -public interface CustomBotAction { - - /** - * Executes the action, returning its success. - * - * @param bot bot of the action - * @return true if once action finish, otherwise false - */ - boolean doTick(Bot bot); - - /** - * Created a new action instance. - * - * @param player player who create this action - * @param args passed action arguments - * @return a new action instance with given args - */ - @Nullable CustomBotAction getNew(@Nullable Player player, String[] args); - - /** - * Requests a list of possible completions for a action argument. - * - * @return A List of a List of possible completions for the argument. - */ - @NotNull List> getTabComplete(); - - /** - * Return the interval between {@link CustomBotAction#doTick(Bot)} - * - * @return the tick interval - */ - int getInitialTickInterval(); - - /** - * Return the tick delay to the first {@link CustomBotAction#doTick(Bot)} - * - * @return the tick delay - */ - int getInitialTickDelay(); - - /** - * Return a number of times {@link CustomBotAction#doTick(Bot)} can return true - * - * @return the number of times an action can be executed - */ - int getInitialNumber(); -} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/LeavesBotAction.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/LeavesBotAction.java deleted file mode 100644 index 939ffa88..00000000 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/botaction/LeavesBotAction.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.leavesmc.leaves.entity.botaction; - -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; - -import java.util.UUID; - -@org.jetbrains.annotations.ApiStatus.Experimental -public class LeavesBotAction { - - private final String actionName; - private final UUID uuid; - private final int initialTickDelay; - private final int initialTickInterval; - private final int initialNumber; - - private Player actionPlayer; - private int tickToNext; - private int numberRemaining; - private boolean cancel; - - public LeavesBotAction(BotActionType type, int initialTickInterval, int initialNumber) { - this(type.getName(), UUID.randomUUID(), 0, initialTickInterval, initialNumber); - } - - public LeavesBotAction(BotActionType type, int initialTickDelay, int initialTickInterval, int initialNumber) { - this(type.getName(), UUID.randomUUID(), initialTickDelay, initialTickInterval, initialNumber); - } - - protected LeavesBotAction(String name, UUID actionUUID, int initialTickDelay, int initialTickInterval, int initialNumber) { - this.actionName = name; - this.uuid = actionUUID; - this.initialTickDelay = initialTickDelay; - this.initialTickInterval = initialTickInterval; - this.initialNumber = initialNumber; - } - - public String getActionName() { - return actionName; - } - - public UUID getUuid() { - return uuid; - } - - public int getInitialTickDelay() { - return initialTickDelay; - } - - public int getInitialTickInterval() { - return initialTickInterval; - } - - public int getInitialNumber() { - return initialNumber; - } - - @Nullable - public Player getActionPlayer() { - return actionPlayer; - } - - public void setActionPlayer(@Nullable Player actionPlayer) { - this.actionPlayer = actionPlayer; - } - - public boolean isCancel() { - return cancel; - } - - public void setCancel(boolean cancel) { - this.cancel = cancel; - } - - public int getNumberRemaining() { - return numberRemaining; - } - - public void setNumberRemaining(int numberRemaining) { - this.numberRemaining = numberRemaining; - } - - public int getTickToNext() { - return tickToNext; - } - - public void setTickToNext(int tickToNext) { - this.tickToNext = tickToNext; - } -} diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/Photographer.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/photographer/Photographer.java similarity index 91% rename from leaves-api/src/main/java/org/leavesmc/leaves/entity/Photographer.java rename to leaves-api/src/main/java/org/leavesmc/leaves/entity/photographer/Photographer.java index 6cc611c7..0ca2a193 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/Photographer.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/photographer/Photographer.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.photographer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/entity/PhotographerManager.java b/leaves-api/src/main/java/org/leavesmc/leaves/entity/photographer/PhotographerManager.java similarity index 94% rename from leaves-api/src/main/java/org/leavesmc/leaves/entity/PhotographerManager.java rename to leaves-api/src/main/java/org/leavesmc/leaves/entity/photographer/PhotographerManager.java index 4a2b67f1..144a089c 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/entity/PhotographerManager.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/entity/photographer/PhotographerManager.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.photographer; import org.bukkit.Location; import org.jetbrains.annotations.NotNull; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionEvent.java index 1818aa77..fcaf302e 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionEvent.java @@ -1,7 +1,7 @@ package org.leavesmc.leaves.event.bot; import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; import java.util.UUID; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionExecuteEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionExecuteEvent.java index d7a41717..9c298ae0 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionExecuteEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionExecuteEvent.java @@ -3,7 +3,7 @@ package org.leavesmc.leaves.event.bot; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; import java.util.UUID; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionScheduleEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionScheduleEvent.java index f92e29ce..f93f1e92 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionScheduleEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionScheduleEvent.java @@ -5,7 +5,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; import java.util.UUID; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionStopEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionStopEvent.java index 1a4772ce..ee79a861 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionStopEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotActionStopEvent.java @@ -5,7 +5,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; import java.util.UUID; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotConfigModifyEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotConfigModifyEvent.java index 4cee1ac5..ce3ec9d5 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotConfigModifyEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotConfigModifyEvent.java @@ -4,7 +4,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; public class BotConfigModifyEvent extends BotEvent implements Cancellable { diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java index c7b22574..90dd5eca 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotCreateEvent.java @@ -20,6 +20,7 @@ public class BotCreateEvent extends Event implements Cancellable { private final CommandSender creator; private Location createLocation; private boolean cancel = false; + public BotCreateEvent(@NotNull final String who, @NotNull final String skin, @NotNull final Location createLocation, @NotNull CreateReason reason, @Nullable CommandSender creator) { this.bot = who; this.skin = skin; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotDeathEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotDeathEvent.java index 2204863a..8709a0f2 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotDeathEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotDeathEvent.java @@ -6,7 +6,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; public class BotDeathEvent extends BotEvent implements Cancellable { diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotEvent.java index ed9f954d..f046c48f 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotEvent.java @@ -2,7 +2,7 @@ package org.leavesmc.leaves.event.bot; import org.bukkit.event.Event; import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; /** * Represents a fakeplayer related event diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java index f525ccdc..e1587ef9 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotInventoryOpenEvent.java @@ -5,7 +5,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; public class BotInventoryOpenEvent extends BotEvent implements Cancellable { diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java index 82b29aea..bef0e306 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotJoinEvent.java @@ -5,7 +5,7 @@ import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; /** * Called when a fakeplayer joins a server diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java index 9bf59445..794e859b 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotRemoveEvent.java @@ -7,7 +7,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; /** * Call when a fakeplayer removed @@ -20,6 +20,7 @@ public class BotRemoveEvent extends BotEvent implements Cancellable { private Component removeMessage; private boolean save; private boolean cancel = false; + public BotRemoveEvent(@NotNull final Bot who, @NotNull RemoveReason reason, @Nullable CommandSender remover, @Nullable Component removeMessage, boolean save) { super(who); this.reason = reason; diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotSpawnLocationEvent.java b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotSpawnLocationEvent.java index b3c5afaf..7528ccdf 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotSpawnLocationEvent.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/event/bot/BotSpawnLocationEvent.java @@ -3,7 +3,7 @@ package org.leavesmc.leaves.event.bot; import org.bukkit.Location; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; public class BotSpawnLocationEvent extends BotEvent { diff --git a/leaves-api/src/main/java/org/leavesmc/leaves/plugin/Features.java b/leaves-api/src/main/java/org/leavesmc/leaves/plugin/Features.java index 00365c93..fc5d2c18 100644 --- a/leaves-api/src/main/java/org/leavesmc/leaves/plugin/Features.java +++ b/leaves-api/src/main/java/org/leavesmc/leaves/plugin/Features.java @@ -5,5 +5,5 @@ public class Features { public static final String MIXIN = "mixin"; public static final String FAKEPLAYER = "fakeplayer"; public static final String PHOTOGRAPHER = "photographer"; - public static final String RECORDER = "recorder"; + public static final String RECORDER = "recorder"; } diff --git a/leaves-server/build.gradle.kts.patch b/leaves-server/build.gradle.kts.patch index 0bec9579..4f3e0457 100644 --- a/leaves-server/build.gradle.kts.patch +++ b/leaves-server/build.gradle.kts.patch @@ -1,10 +1,16 @@ --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts -@@ -9,25 +_,38 @@ +@@ -1,4 +_,3 @@ +-import io.papermc.fill.model.BuildChannel + import io.papermc.paperweight.attribute.DevBundleOutput + import io.papermc.paperweight.util.* + import io.papermc.paperweight.util.data.FileEntry +@@ -10,24 +_,36 @@ `java-library` `maven-publish` idea - id("io.papermc.paperweight.core") +- id("io.papermc.fill.gradle") version "1.0.7" + id("org.leavesmc.leavesweight.core") // Leaves - build change } @@ -12,9 +18,9 @@ +val leavesMavenPublicUrl = "https://repo.leavesmc.com/snapshots/" // Leaves - build change dependencies { - mache("io.papermc:mache:1.21.5+build.2") + mache("io.papermc:mache:1.21.8+build.1") - paperclip("io.papermc:paperclip:3.0.3") -+ leavesclip("org.leavesmc:leavesclip:3.0.0") // Leaves - build change ++ leavesclip("org.leavesmc:leavesclip:3.0.4") // Leaves - build change testRuntimeOnly("org.junit.platform:junit-platform-launcher") } @@ -23,10 +29,6 @@ + minecraftVersion = rootProject.providers.gradleProperty("mcVersion") // Leaves - build change gitFilePatches = false - //updatingMinecraft { - // oldPaperCommit = "f4f275519f7c1fbe9db173b7144a4fe81440e365" - //} - + // Leaves start - build change + val leaves = forks.register("leaves") { + upstream.patchDir("paperServer") { @@ -40,9 +42,12 @@ + // Leaves end - build change + spigot { - buildDataRef = "702e1a0a5072b2c4082371d5228cb30525687efc" - packageVersion = "v1_21_R4" // also needs to be updated in MappingEnvironment -@@ -50,6 +_,7 @@ +- enabled = true ++ // enabled = true // Leaves - disable + buildDataRef = "436eac9815c211be1a2a6ca0702615f995e81c44" + packageVersion = "v1_21_R5" // also needs to be updated in MappingEnvironment + } +@@ -49,6 +_,7 @@ libraryRepositories.addAll( "https://repo.maven.apache.org/maven2/", paperMavenPublicUrl, @@ -50,7 +55,7 @@ ) } -@@ -108,7 +_,22 @@ +@@ -107,7 +_,22 @@ } } @@ -74,12 +79,13 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { extendsFrom(configurations.compileClasspath.get()) } -@@ -130,7 +_,18 @@ +@@ -129,7 +_,19 @@ } dependencies { - implementation(project(":paper-api")) + implementation(project(":leaves-api")) // Leaves - build change ++ implementation("commons-lang:commons-lang:2.6") // Leaves - build change + // Leaves start - linear + implementation("com.github.luben:zstd-jni:1.5.4-1") + implementation("org.lz4:lz4-java:1.8.0") @@ -94,18 +100,15 @@ implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 -@@ -157,9 +_,9 @@ - implementation("org.ow2.asm:asm-commons:9.8") - implementation("org.spongepowered:configurate-yaml:4.2.0-20250225.064233-199") - implementation("org.spongepowered:configurate-core:4.2.0-20250225.064233-204") // Pinned dependency of above pinned yaml snapshot. -+ implementation("commons-lang:commons-lang:2.6") // Leaves +@@ -157,7 +_,6 @@ + implementation("org.spongepowered:configurate-yaml:4.2.0") // Deps that were previously in the API but have now been moved here for backwards compat, eventually to be removed - runtimeOnly("commons-lang:commons-lang:2.6") runtimeOnly("org.xerial:sqlite-jdbc:3.49.1.0") runtimeOnly("com.mysql:mysql-connector-j:9.2.0") runtimeOnly("com.lmax:disruptor:3.4.4") -@@ -194,6 +_,16 @@ +@@ -188,26 +_,36 @@ implementation("me.lucko:spark-paper:1.10.133-20250413.112336-1") } @@ -122,7 +125,13 @@ tasks.jar { manifest { val git = Git(rootProject.layout.projectDirectory.path) -@@ -206,14 +_,14 @@ + val mcVersion = rootProject.providers.gradleProperty("mcVersion").get() + val build = System.getenv("BUILD_NUMBER") ?: null +- val buildTime = if (build != null) Instant.now() else Instant.EPOCH ++ val buildTime = Instant.now() // Leaves - always use build time + val gitHash = git.exec(providers, "rev-parse", "--short=7", "HEAD").get().trim() + val implementationVersion = "$mcVersion-${build ?: "DEV"}-$gitHash" + val date = git.exec(providers, "show", "-s", "--format=%ci", gitHash).get().trim() val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim() attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", @@ -142,16 +151,27 @@ "Build-Number" to (build ?: ""), "Build-Time" to buildTime.toString(), "Git-Branch" to gitBranch, -@@ -267,7 +_,7 @@ +@@ -266,7 +_,7 @@ jvmArgumentProviders.add(provider) } -val generatedDir: java.nio.file.Path = layout.projectDirectory.dir("src/generated/java").asFile.toPath() -+val generatedDir: java.nio.file.Path = rootProject.layout.projectDirectory.dir("paper-server/src/generated/java").asFile.toPath() ++val generatedDir: java.nio.file.Path = rootProject.layout.projectDirectory.dir("paper-server/src/generated/java").asFile.toPath() // Leaves - build change idea { module { generatedSourceDirs.add(generatedDir.toFile()) -@@ -360,13 +_,26 @@ +@@ -315,6 +_,10 @@ + } + + args("--nogui") ++ systemProperty("stdout.encoding", "UTF-8") // Leaves - fix utf8 ++ systemProperty("stderr.encoding", "UTF-8") // Leaves - fix utf8 ++ systemProperty("net.kyori.ansi.colorLevel", "truecolor") // Leaves - fix utf8 ++ systemProperty("terminal.jline", true) // Leaves - fix utf8 + systemProperty("net.kyori.adventure.text.warnWhenLegacyFormattingDetected", true) + if (providers.gradleProperty("paper.runDisableWatchdog").getOrElse("false") == "true") { + systemProperty("disable.watchdog", true) +@@ -359,30 +_,26 @@ classpath(tasks.createReobfBundlerJar.flatMap { it.outputZip }) mainClass.set(null as String?) } @@ -165,6 +185,23 @@ - classpath(tasks.createReobfPaperclipJar.flatMap { it.outputZip }) - mainClass.set(null as String?) -} +- +-fill { +- project("paper") +- versionFamily(paperweight.minecraftVersion.map { it.split(".", "-").takeWhile { part -> part.toIntOrNull() != null }.take(2).joinToString(".") }) +- version(paperweight.minecraftVersion) +- +- build { +- channel = BuildChannel.STABLE +- +- downloads { +- register("server:default") { +- file = tasks.createMojmapPaperclipJar.flatMap { it.outputZip } +- nameResolver.set { project, _, version, build -> "$project-$version-$build.jar" } +- } +- } +- } +-} + +// Leaves start - build change +tasks.registerRunTask("runLeavesclip") { diff --git a/leaves-server/minecraft-patches/features/0001-Build-changes.patch b/leaves-server/minecraft-patches/features/0001-Build-changes.patch index b63bea7a..ae01110d 100644 --- a/leaves-server/minecraft-patches/features/0001-Build-changes.patch +++ b/leaves-server/minecraft-patches/features/0001-Build-changes.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Build changes diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java -index b9b774a3ca600cee3d0e967063ea2f72c7ab184f..dfc582444cd7273afb78b250d9fa12317591d8aa 100644 +index 42899a91b9061b85985fbbd0de4032c757f4aa8f..a93f00d1a64e4deb9b89435bab258f3bad487e2f 100644 --- a/ca/spottedleaf/moonrise/paper/PaperHooks.java +++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java @@ -29,7 +29,7 @@ import net.minecraft.world.phys.AABB; @@ -15,13 +15,13 @@ index b9b774a3ca600cee3d0e967063ea2f72c7ab184f..dfc582444cd7273afb78b250d9fa1231 -public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks { +public class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks { // Leaves - not final - @Override - public String getBrand() { + private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); + diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index f1373fd5fdebb9f4600ba7f32a5df6188de3a0e9..4e5b27f2d00a6be6da6db461471395a515dc9b38 100644 +index 7aac2a6889af3edaebfaf94deecbf00d00758b68..d2895962ad3879632ff7a33eb3ce656097aebaec 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1190,7 +1190,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, AutoCl + return this.isClientSide; + } + +- @Nullable ++ @org.jetbrains.annotations.NotNull // Leaves - notnull + @Override + public MinecraftServer getServer() { + return null; +diff --git a/net/minecraft/world/level/LevelAccessor.java b/net/minecraft/world/level/LevelAccessor.java +index 5f28df24876f93866312c3c7d19cb6bcaf5e2f8b..049133cba588612127b45c1489f80d2fe6d6e330 100644 +--- a/net/minecraft/world/level/LevelAccessor.java ++++ b/net/minecraft/world/level/LevelAccessor.java +@@ -46,7 +46,7 @@ public interface LevelAccessor extends CommonLevelAccessor, LevelTimeAccess, Sch + + DifficultyInstance getCurrentDifficultyAt(BlockPos pos); + +- @Nullable ++ @org.jetbrains.annotations.NotNull // Leaves - notnull + MinecraftServer getServer(); + + default Difficulty getDifficulty() { diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java -index ae3e6e31171b1bcfba1ae51a0941b52dda270acd..f289e37f77e1c9d3b0f6c29da1b99f0d5f156e37 100644 +index be6f37f91569c659c609e5e8d38671ca86f8cd95..958914e40fceda5d67a98154817b4c5ce478a62d 100644 --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java @@ -610,6 +610,13 @@ public class Block extends BlockBehaviour implements ItemLike { diff --git a/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch b/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch index cab762f4..b7d20279 100644 --- a/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch +++ b/leaves-server/minecraft-patches/features/0004-Leaves-Protocol-Core.patch @@ -32,30 +32,11 @@ index fb263fa1f30a7dfcb7ec2656abfb38e5fe88eac9..56fd1ed7ccaf96e7eedea60fbdbf7f93 } }; } -diff --git a/net/minecraft/network/protocol/common/custom/DiscardedPayload.java b/net/minecraft/network/protocol/common/custom/DiscardedPayload.java -index 62b9d9486c15a1ec6527f786df4e9fc483390bcb..5384bbc6bb3dbe5481f9d8cb10282551a0f78ec1 100644 ---- a/net/minecraft/network/protocol/common/custom/DiscardedPayload.java -+++ b/net/minecraft/network/protocol/common/custom/DiscardedPayload.java -@@ -4,12 +4,12 @@ import net.minecraft.network.FriendlyByteBuf; - import net.minecraft.network.codec.StreamCodec; - import net.minecraft.resources.ResourceLocation; - --public record DiscardedPayload(ResourceLocation id, byte[] data) implements CustomPacketPayload { // Paper - store data -+public record DiscardedPayload(ResourceLocation id, byte @org.jetbrains.annotations.Nullable [] data) implements CustomPacketPayload { // Paper - store data // Leaves - nullable - public static StreamCodec codec(ResourceLocation id, int maxSize) { - return CustomPacketPayload.codec((value, output) -> { - // Paper start - // Always write data -- output.writeBytes(value.data); -+ if (value.data != null) output.writeBytes(value.data); // Leaves - nullable - }, buffer -> { - int i = buffer.readableBytes(); - if (i >= 0 && i <= maxSize) { diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 4e5b27f2d00a6be6da6db461471395a515dc9b38..d48581353661799e5e031a512227d5e651fa2996 100644 +index d2895962ad3879632ff7a33eb3ce656097aebaec..4e2e84bbd389d926b8e6f45f2e37c80f4df1af41 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1742,6 +1742,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginMessagerChannels; + // Paper end - retain certain values ++ public final GameProfile profile; // Leaves - protocol core + + public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) { + this.server = server; +@@ -70,6 +71,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack + this.pluginMessagerChannels = cookie.channels(); + this.keepAlive = cookie.keepAlive(); + // Paper end ++ this.profile = cookie.gameProfile(); // Leaves - protocol core + } + + // Paper start - configuration phase API +@@ -149,6 +151,18 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { + // Leaves start - protocol + if (packet.payload() instanceof org.leavesmc.leaves.protocol.core.LeavesCustomPayload leavesPayload) { -+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(player, leavesPayload); ++ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePayload(org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this), leavesPayload); + return; + } + if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.DiscardedPayload(net.minecraft.resources.ResourceLocation id, byte[] data)) { -+ if (org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleBytebuf(player, id, io.netty.buffer.Unpooled.wrappedBuffer(data))) { ++ if (org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleBytebuf(org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this), id, io.netty.buffer.Unpooled.wrappedBuffer(data))) { + return; + } + } + // Leaves end - protocol + // Paper start - if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload(String brand)) { - this.player.clientBrandName = brand; -@@ -189,6 +201,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack + if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) { + return; +@@ -208,10 +222,11 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII); if (register) { - this.getCraftPlayer().addChannel(channel); -+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, player); // Leaves - protocol + bridge.addChannel(channel); ++ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handleMinecraftRegister(channel, org.leavesmc.leaves.protocol.core.ProtocolUtils.createSelector(this)); // Leaves - protocol } else { - this.getCraftPlayer().removeChannel(channel); + bridge.removeChannel(channel); } +- // Paper end ++ // Paper end + } + + @Override +@@ -379,9 +394,9 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack + net.minecraft.server.level.ServerPlayer player = serverGamePacketListener.player; + org.bukkit.event.player.PlayerKickEvent.Cause cause = disconnectionDetails.disconnectionReason().orElseThrow().game().orElse(org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); + org.bukkit.event.player.PlayerKickEvent event = new org.bukkit.event.player.PlayerKickEvent( +- player.getBukkitEntity(), +- io.papermc.paper.adventure.PaperAdventure.asAdventure(disconnectionDetails.reason()), +- rawLeaveMessage, cause ++ player.getBukkitEntity(), ++ io.papermc.paper.adventure.PaperAdventure.asAdventure(disconnectionDetails.reason()), ++ rawLeaveMessage, cause + + ); + +@@ -414,10 +429,10 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack + + private void disconnect0(DisconnectionDetails disconnectionDetails) { + this.connection +- .send( +- new ClientboundDisconnectPacket(disconnectionDetails.reason()), +- PacketSendListener.thenRun(() -> this.connection.disconnect(disconnectionDetails)) +- ); ++ .send( ++ new ClientboundDisconnectPacket(disconnectionDetails.reason()), ++ PacketSendListener.thenRun(() -> this.connection.disconnect(disconnectionDetails)) ++ ); + this.onDisconnect(disconnectionDetails); + this.connection.setReadOnly(); + // CraftBukkit - Don't wait diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 9ca3c55a3b5b1a532b86b08eb92460df4cb54f2a..722b4eb1eabe167233f75bd50bbf47e369670eaa 100644 +index 2c2015bf19d5b30e945118661b7a9b474a1bddc8..87d6495738d27b2cc9ea8d5b402b7c222f624a5b 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -334,6 +334,11 @@ public abstract class PlayerList { - return; - } +@@ -335,6 +335,8 @@ public abstract class PlayerList { + return; + } -+ // Leaves start - protocol core -+ if (player.internalConnection == null) player.internalConnection = connection; -+ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); -+ // Leaves end - protocol core ++ org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); + - final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); + final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); - if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure -@@ -504,6 +509,7 @@ public abstract class PlayerList { + if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure +@@ -507,6 +509,7 @@ public abstract class PlayerList { return this.remove(player, net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? player.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(player.getDisplayName()))); } public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) { + org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(player); // Leaves - protocol // Paper end - Fix kick event leave message not being sent - ServerLevel serverLevel = player.serverLevel(); + ServerLevel serverLevel = player.level(); player.awardStat(Stats.LEAVE_GAME); -@@ -628,6 +634,7 @@ public abstract class PlayerList { - SocketAddress socketAddress = loginlistener.connection.getRemoteAddress(); - - ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, ClientInformation.createDefault()); -+ entity.internalConnection = loginlistener.connection; // Leaves - protocol core - entity.transferCookieConnection = loginlistener; - org.bukkit.entity.Player player = entity.getBukkitEntity(); - org.bukkit.event.player.PlayerLoginEvent event = new org.bukkit.event.player.PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketAddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); -@@ -1418,6 +1425,7 @@ public abstract class PlayerList { +@@ -1398,6 +1401,7 @@ public abstract class PlayerList { serverPlayer.connection.send(clientboundUpdateRecipesPacket); serverPlayer.getRecipeBook().sendInitialRecipeBook(serverPlayer); } diff --git a/leaves-server/minecraft-patches/features/0005-Configurable-trading-with-the-void.patch b/leaves-server/minecraft-patches/features/0005-Configurable-trading-with-the-void.patch index 61ab739e..65b248f2 100644 --- a/leaves-server/minecraft-patches/features/0005-Configurable-trading-with-the-void.patch +++ b/leaves-server/minecraft-patches/features/0005-Configurable-trading-with-the-void.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable trading with the void diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index bfbfbaa9660d21071c420b60b10be0a02a1bc87e..4797e001122097f55f33729b3b20f79d75b20fb2 100644 +index dda8d38ef61672cc714d9e5a475f9b0412ed5ff9..364d5e28646ea341034921622354c7b19644b343 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -2674,7 +2674,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2727,7 +2727,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Spigot start if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message // Paper start - Fix merchant inventory not closing on entity removal @@ -17,6 +17,19 @@ index bfbfbaa9660d21071c420b60b10be0a02a1bc87e..4797e001122097f55f33729b3b20f79d merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); } // Paper end - Fix merchant inventory not closing on entity removal +diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java +index 91f505c9d84aba773d237664c2aaaf9750cadadf..184d116320f0cd3e9fba47a86e94e0a8424c913f 100644 +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -551,7 +551,7 @@ public abstract class PlayerList { + player.stopRiding(); + rootVehicle.getPassengersAndSelf().forEach(entity -> { + // Paper start - Fix villager boat exploit +- if (entity instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.voidTrade && entity instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { // Leaves - Configurable trading with the void + final net.minecraft.world.entity.player.Player human = villager.getTradingPlayer(); + if (human != null) { + villager.setTradingPlayer(null); diff --git a/net/minecraft/world/inventory/MerchantMenu.java b/net/minecraft/world/inventory/MerchantMenu.java index d59f67ffe34201c63e3d9706a4434f33b6732edb..1bf2a015fa35981328c098f2fec363c84b85b2a7 100644 --- a/net/minecraft/world/inventory/MerchantMenu.java diff --git a/leaves-server/minecraft-patches/features/0007-Leaves-Fakeplayer.patch b/leaves-server/minecraft-patches/features/0007-Leaves-Fakeplayer.patch index bd5cfbb1..3881d970 100644 --- a/leaves-server/minecraft-patches/features/0007-Leaves-Fakeplayer.patch +++ b/leaves-server/minecraft-patches/features/0007-Leaves-Fakeplayer.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Leaves Fakeplayer diff --git a/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java b/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java -index 4b2ae046413146b11912e7aa4a9a3d643de6afd1..c5733fe17b4dd5dfe4bce461a305a13a188b2f77 100644 +index a82d84283632342bd30bc3449983431ba43583e0..f59526f6bfa1b4af5b474f0b438513c96afb491c 100644 --- a/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java +++ b/net/minecraft/advancements/critereon/SimpleCriterionTrigger.java @@ -39,6 +39,7 @@ public abstract class SimpleCriterionTrigger> set = (Set) advancements.criterionData.get(this); // Paper - fix PlayerAdvancements leak if (set != null && !set.isEmpty()) { diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 4ed9611994c5c8da01fede690197527c5b3a5731..364ddf9f25ef3cb97ba788c469fee9dd495b84a7 100644 +index 41005f6b9f53a9c1125ad5e08538d9f5aacb3571..3e9b8c5fb2157f767de8bddc3e767512c5f7651f 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -96,7 +96,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -30,28 +30,19 @@ index 4ed9611994c5c8da01fede690197527c5b3a5731..364ddf9f25ef3cb97ba788c469fee9dd private DisconnectionDetails disconnectionDetails; private boolean encrypted; diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index d48581353661799e5e031a512227d5e651fa2996..b0881eaf3484560740d2d53b3957cf3f4d829360 100644 +index 4e2e84bbd389d926b8e6f45f2e37c80f4df1af41..83b81e990fccebad35c67712d0d497537c4e3670 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -303,6 +303,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation + private org.leavesmc.leaves.bot.BotList botList; // Leaves - fakeplayer + public static S spin(Function threadFunction) { + ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system AtomicReference atomicReference = new AtomicReference<>(); - Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> atomicReference.get().runServer(), "Server thread"); -@@ -738,6 +740,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> optional = PoiTypes.forState(oldState); -@@ -2616,6 +2624,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2661,6 +2669,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true if (entity instanceof ServerPlayer serverPlayer) { ServerLevel.this.players.add(serverPlayer); @@ -172,10 +171,10 @@ index 4797e001122097f55f33729b3b20f79d75b20fb2..9c32960a14916f3b032c6ae323d6efc9 + ServerLevel.this.realPlayers.add(serverPlayer); + } + // Leaves end - skip - ServerLevel.this.updateSleepingPlayerList(); - } - -@@ -2686,6 +2699,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + if (serverPlayer.isReceivingWaypoints()) { + ServerLevel.this.getWaypointManager().addPlayer(serverPlayer); + } +@@ -2739,6 +2752,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer serverPlayer) { ServerLevel.this.players.remove(serverPlayer); @@ -184,59 +183,59 @@ index 4797e001122097f55f33729b3b20f79d75b20fb2..9c32960a14916f3b032c6ae323d6efc9 + ServerLevel.this.realPlayers.remove(serverPlayer); + } + // Leaves end - skip + ServerLevel.this.getWaypointManager().removePlayer(serverPlayer); ServerLevel.this.updateSleepingPlayerList(); } - diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 443bfb06951f0ffe6af8724b53e150cd0907e68d..01687ea3acf449c49cbc615887a7dbdd3a693613 100644 +index 37c0a84758a1526791913898358659de202fa19f..7e4bf7ddc26fc087832f802856f14e268b0ca32b 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -208,7 +208,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -219,7 +219,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc private static final boolean DEFAULT_SPAWN_EXTRA_PARTICLES_ON_FALL = false; public ServerGamePacketListenerImpl connection; - public final MinecraftServer server; + private final MinecraftServer server; - public final ServerPlayerGameMode gameMode; + public ServerPlayerGameMode gameMode; // Leaves - not final private final PlayerAdvancements advancements; private final ServerStatsCounter stats; private float lastRecordedHealthAndAbsorption = Float.MIN_VALUE; -@@ -1413,6 +1413,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1450,6 +1450,11 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc this.lastSentHealth = -1.0F; this.lastSentFood = -1; - + this.teleportSpectators(teleportTransition, serverLevel); + // Leaves start - bot support + if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { + this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(this, true)); // Leaves - render bot + } + // Leaves end - bot support - // CraftBukkit start org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), serverLevel.getWorld()); + this.level().getCraftServer().getPluginManager().callEvent(changeEvent); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 722b4eb1eabe167233f75bd50bbf47e369670eaa..0cf30681a9e3d68f3abe1d87b9fd4220083685a9 100644 +index bd3cb8d68ac2940cd6f3b28a91c17ebc64147f2d..204c25d33e86a736f091848a277ea882f129e468 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -339,6 +339,19 @@ public abstract class PlayerList { - org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); - // Leaves end - protocol core +@@ -337,6 +337,19 @@ public abstract class PlayerList { -+ // Leaves start - bot support -+ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { -+ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName()); -+ if (bot != null) { -+ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false); + org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); + ++ // Leaves start - bot support ++ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { ++ org.leavesmc.leaves.bot.ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName()); ++ if (bot != null) { ++ this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false); ++ } ++ this.server.getBotList().bots.forEach(bot1 -> { ++ bot1.sendPlayerInfo(player); ++ bot1.sendFakeDataIfNeed(player, true); ++ }); // Leaves - render bot + } -+ this.server.getBotList().bots.forEach(bot1 -> { -+ bot1.sendPlayerInfo(player); -+ bot1.sendFakeDataIfNeed(player, true); -+ }); // Leaves - render bot -+ } -+ // Leaves end - bot support ++ // Leaves end - bot support + - final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); + final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); - if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure -@@ -870,6 +883,12 @@ public abstract class PlayerList { + if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure +@@ -829,6 +842,12 @@ public abstract class PlayerList { } // Paper end - Add PlayerPostRespawnEvent @@ -249,7 +248,7 @@ index 722b4eb1eabe167233f75bd50bbf47e369670eaa..0cf30681a9e3d68f3abe1d87b9fd4220 // CraftBukkit end return serverPlayer; -@@ -974,11 +993,16 @@ public abstract class PlayerList { +@@ -933,11 +952,16 @@ public abstract class PlayerList { } public String[] getPlayerNamesArray() { @@ -267,7 +266,7 @@ index 722b4eb1eabe167233f75bd50bbf47e369670eaa..0cf30681a9e3d68f3abe1d87b9fd4220 return strings; } -@@ -1064,7 +1088,14 @@ public abstract class PlayerList { +@@ -1040,7 +1064,14 @@ public abstract class PlayerList { @Nullable public ServerPlayer getPlayerByName(String username) { @@ -283,7 +282,7 @@ index 722b4eb1eabe167233f75bd50bbf47e369670eaa..0cf30681a9e3d68f3abe1d87b9fd4220 } public void broadcast(@Nullable Player except, double x, double y, double z, double radius, ResourceKey dimension, Packet packet) { -@@ -1380,7 +1411,13 @@ public abstract class PlayerList { +@@ -1356,7 +1387,13 @@ public abstract class PlayerList { @Nullable public ServerPlayer getPlayer(UUID playerUUID) { @@ -298,11 +297,48 @@ index 722b4eb1eabe167233f75bd50bbf47e369670eaa..0cf30681a9e3d68f3abe1d87b9fd4220 } public boolean canBypassPlayerLimit(GameProfile profile) { +diff --git a/net/minecraft/server/waypoints/ServerWaypointManager.java b/net/minecraft/server/waypoints/ServerWaypointManager.java +index f9e7532f86122a379692561a639a209a126e8bba..2412f46837e967694222730e68e7d25ac32225cf 100644 +--- a/net/minecraft/server/waypoints/ServerWaypointManager.java ++++ b/net/minecraft/server/waypoints/ServerWaypointManager.java +@@ -22,6 +22,11 @@ public class ServerWaypointManager implements WaypointManager lastDeathLocation = Optional.empty(); @Nullable -@@ -362,6 +362,12 @@ public abstract class Player extends LivingEntity { +@@ -372,6 +372,12 @@ public abstract class Player extends LivingEntity { } } @@ -337,7 +373,7 @@ index 2046c4d3ad5ea3254ad6bc83e6437e5c237c92b6..2fe76bc1c26423ed5e39453ac1b27a2c @Override protected float getMaxHeadRotationRelativeToBody() { return this.isBlocking() ? 15.0F : super.getMaxHeadRotationRelativeToBody(); -@@ -664,7 +670,7 @@ public abstract class Player extends LivingEntity { +@@ -674,7 +680,7 @@ public abstract class Player extends LivingEntity { } } @@ -346,7 +382,7 @@ index 2046c4d3ad5ea3254ad6bc83e6437e5c237c92b6..2fe76bc1c26423ed5e39453ac1b27a2c entity.playerTouch(this); } -@@ -1287,7 +1293,7 @@ public abstract class Player extends LivingEntity { +@@ -1299,7 +1305,7 @@ public abstract class Player extends LivingEntity { this.sweepAttack(); } @@ -356,10 +392,10 @@ index 2046c4d3ad5ea3254ad6bc83e6437e5c237c92b6..2fe76bc1c26423ed5e39453ac1b27a2c boolean cancelled = false; org.bukkit.entity.Player player = (org.bukkit.entity.Player) target.getBukkitEntity(); diff --git a/net/minecraft/world/entity/projectile/FishingHook.java b/net/minecraft/world/entity/projectile/FishingHook.java -index ca5cd9354d53c6c05bd7ba50c6e1dbd1ed548f67..f82f37d498f99ce38f72a63d051721c6dab9f2ca 100644 +index 5f3abbe943be394e9cb987945a238208940b5015..8c139d572bd3c44b8e2b6205e28ab09f82c9abfe 100644 --- a/net/minecraft/world/entity/projectile/FishingHook.java +++ b/net/minecraft/world/entity/projectile/FishingHook.java -@@ -55,7 +55,7 @@ public class FishingHook extends Projectile { +@@ -58,7 +58,7 @@ public class FishingHook extends Projectile { public static final EntityDataAccessor DATA_HOOKED_ENTITY = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_BITING = SynchedEntityData.defineId(FishingHook.class, EntityDataSerializers.BOOLEAN); private int life; @@ -369,10 +405,10 @@ index ca5cd9354d53c6c05bd7ba50c6e1dbd1ed548f67..f82f37d498f99ce38f72a63d051721c6 public int timeUntilHooked; public float fishAngle; diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index 813417a09b4acc7d57e80a53d970767e230d75b1..2a4763c951ddc78c9d8a39e661e59bbffc5cf109 100644 +index 96da9b8e3556e58365dc6742f44d6dfd608e2953..e5811924577fb04fd2d67fb4a32a9de1dbe3c7b1 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -376,6 +376,7 @@ public abstract class AbstractContainerMenu { +@@ -400,6 +400,7 @@ public abstract class AbstractContainerMenu { private void doClick(int slotId, int button, ClickType clickType, Player player) { Inventory inventory = player.getInventory(); @@ -380,7 +416,7 @@ index 813417a09b4acc7d57e80a53d970767e230d75b1..2a4763c951ddc78c9d8a39e661e59bbf if (clickType == ClickType.QUICK_CRAFT) { int i = this.quickcraftStatus; this.quickcraftStatus = getQuickcraftHeader(button); -@@ -652,6 +653,22 @@ public abstract class AbstractContainerMenu { +@@ -674,6 +675,22 @@ public abstract class AbstractContainerMenu { } } @@ -404,10 +440,10 @@ index 813417a09b4acc7d57e80a53d970767e230d75b1..2a4763c951ddc78c9d8a39e661e59bbf FeatureFlagSet featureFlagSet = player.level().enabledFeatures(); return carriedItem.isItemEnabled(featureFlagSet) && carriedItem.overrideStackedOnOther(slot, action, player) diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index 1669b76800756000a2f620610b3c8c8b6c48dd4a..8449545bd5278f5558567dd6b7c1522f63045f22 100644 +index f1ce4cff1c03a0037ade2c8ef989cf327c973a7e..0976aef81b950a062152094501372d00c20bb2b7 100644 --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -136,7 +136,7 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -135,7 +135,7 @@ public class PistonMovingBlockEntity extends BlockEntity { break; } @@ -446,10 +482,10 @@ index bef794c3f58c41d910aa0bcc63fbdeea7225fddf..a601da588e6973cc5b87d3e3eeba49b5 } diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java -index ab9282c04c1996b037567d07f95e2b150bcfcd38..91f2e0abd1e6d5ad1613b8f750a900bfc39b2f9e 100644 +index fe44d8d17d2622b3d6021c11579af85ef96737bb..0aae211dc2048f8cd14213c2a868394d1ed16070 100644 --- a/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/net/minecraft/world/level/storage/PlayerDataStorage.java -@@ -18,7 +18,7 @@ import net.minecraft.util.datafix.DataFixTypes; +@@ -19,7 +19,7 @@ import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import org.slf4j.Logger; diff --git a/leaves-server/minecraft-patches/features/0008-Make-shears-in-dispenser-can-unlimited-use.patch b/leaves-server/minecraft-patches/features/0008-Make-shears-in-dispenser-can-unlimited-use.patch index 571124f7..b4cf29a7 100644 --- a/leaves-server/minecraft-patches/features/0008-Make-shears-in-dispenser-can-unlimited-use.patch +++ b/leaves-server/minecraft-patches/features/0008-Make-shears-in-dispenser-can-unlimited-use.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Make shears in dispenser can unlimited use diff --git a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index c1bd6d91cf9828ccc7275efe0f5c959c0f457c13..310e4bd5bd0c447adc70cff6d414f88be1966d04 100644 +index b4a9be09452a889c228612a466b8925cb3768102..38442a054bbe87db8dcfab20147d19b2c758d225 100644 --- a/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java @@ -45,7 +45,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING)); - this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item, bukkitBlock, craftItem)); // CraftBukkit + this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearEntity(serverLevel, blockPos, item, bukkitBlock, craftItem)); // CraftBukkit if (this.isSuccess()) { - item.hurtAndBreak(1, serverLevel, null, item1 -> {}); + item.hurtAndBreak(1, serverLevel, null, item1 -> { if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.shearsInDispenserCanZeroAmount) item.grow(1); }); // Leaves - Make shears in dispenser can unlimited use diff --git a/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch b/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch index 0a3aaf74..7e74129f 100644 --- a/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch +++ b/leaves-server/minecraft-patches/features/0009-Redstone-Shears-Wrench.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Redstone Shears Wrench diff --git a/net/minecraft/world/item/ShearsItem.java b/net/minecraft/world/item/ShearsItem.java -index 8cf3e51e12f9cf98836657e722edb23943f9e866..813a6d2bfe99ad8ddf81d7dfca51a7544b5fef0d 100644 +index 8cf3e51e12f9cf98836657e722edb23943f9e866..4705004e4a7c36836e3a4c82412e54d0015cfef6 100644 --- a/net/minecraft/world/item/ShearsItem.java +++ b/net/minecraft/world/item/ShearsItem.java -@@ -24,6 +24,22 @@ import net.minecraft.world.level.block.GrowingPlantHeadBlock; +@@ -24,6 +24,30 @@ import net.minecraft.world.level.block.GrowingPlantHeadBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; @@ -23,31 +23,70 @@ index 8cf3e51e12f9cf98836657e722edb23943f9e866..813a6d2bfe99ad8ddf81d7dfca51a754 +import net.minecraft.world.level.block.CrafterBlock; +import net.minecraft.world.level.block.LeverBlock; +import net.minecraft.world.level.block.CocoaBlock; ++import net.minecraft.world.level.block.TrapDoorBlock; ++import net.minecraft.world.level.block.FenceGateBlock; ++import net.minecraft.world.level.block.LightningRodBlock; ++import net.minecraft.world.level.block.RailBlock; ++import net.minecraft.world.level.block.BaseRailBlock; ++import net.minecraft.world.level.block.PoweredRailBlock; ++import net.minecraft.world.level.block.CalibratedSculkSensorBlock; +import net.minecraft.world.level.block.piston.PistonBaseBlock; +import net.minecraft.world.level.block.state.StateDefinition; ++import net.minecraft.world.level.block.state.properties.RailShape; +import net.minecraft.world.level.block.state.properties.Property; +// Leaves end - shears wrench + public class ShearsItem extends Item { public ShearsItem(Item.Properties properties) { super(properties); -@@ -80,7 +96,68 @@ public class ShearsItem extends Item { +@@ -80,7 +104,108 @@ public class ShearsItem extends Item { return InteractionResult.SUCCESS; } else { + // Leaves start - shears wrench + Block block = blockState.getBlock(); -+ if (org.leavesmc.leaves.LeavesConfig.modify.redstoneShearsWrench && block instanceof ObserverBlock || block instanceof DispenserBlock || -+ block instanceof PistonBaseBlock || block instanceof HopperBlock || block instanceof RepeaterBlock || block instanceof ComparatorBlock || -+ block instanceof CrafterBlock || block instanceof LeverBlock || block instanceof CocoaBlock) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.redstoneShearsWrench && ++ block instanceof ObserverBlock || ++ block instanceof DispenserBlock || ++ block instanceof PistonBaseBlock || ++ block instanceof HopperBlock || ++ block instanceof RepeaterBlock || ++ block instanceof ComparatorBlock || ++ block instanceof CrafterBlock || ++ block instanceof LeverBlock || ++ block instanceof CocoaBlock || ++ block instanceof TrapDoorBlock || ++ block instanceof FenceGateBlock || ++ block instanceof LightningRodBlock || ++ block instanceof CalibratedSculkSensorBlock || ++ block instanceof BaseRailBlock ++ ) { + StateDefinition blockstatelist = block.getStateDefinition(); -+ Property iblockstate = block instanceof CrafterBlock ? blockstatelist.getProperty("orientation") : blockstatelist.getProperty("facing"); ++ Property iblockstate; ++ if (block instanceof CrafterBlock) iblockstate = blockstatelist.getProperty("orientation"); ++ else if (block instanceof BaseRailBlock) iblockstate = blockstatelist.getProperty("shape"); ++ else iblockstate = blockstatelist.getProperty("facing"); + Player player = context.getPlayer(); + + if (iblockstate == null || player == null) { + return InteractionResult.FAIL; + } + ++ if (block instanceof BaseRailBlock) { ++ if (block instanceof RailBlock) { ++ if (blockState.getValue(RailBlock.SHAPE).isSlope()) { ++ return InteractionResult.FAIL; ++ } ++ } else { ++ if (getNameHelper(blockState, PoweredRailBlock.POWERED).equals("true")) { ++ return InteractionResult.FAIL; ++ } ++ if (blockState.getValue(PoweredRailBlock.SHAPE).isSlope()) { ++ return InteractionResult.FAIL; ++ } ++ } ++ } ++ + if (block instanceof PistonBaseBlock) { + if (getNameHelper(blockState, PistonBaseBlock.EXTENDED).equals("true")) { + return InteractionResult.FAIL; @@ -84,7 +123,16 @@ index 8cf3e51e12f9cf98836657e722edb23943f9e866..813a6d2bfe99ad8ddf81d7dfca51a754 + + // Leaves start - shears wrench + private static > BlockState cycleState(BlockState state, Property property, boolean inverse) { -+ return state.setValue(property, ShearsItem.getRelative(property.getPossibleValues(), state.getValue(property), inverse)); // CraftBukkit - decompile error ++ List possibleValues = property.getPossibleValues(); ++ if (possibleValues.getFirst() instanceof RailShape) { ++ boolean isRailBlock = state.getBlock() instanceof RailBlock; ++ possibleValues = possibleValues.stream().filter(possibleValue -> { ++ RailShape shape = (RailShape) possibleValue; ++ if (isRailBlock) return !shape.isSlope(); ++ return !shape.isSlope() && shape != RailShape.NORTH_EAST && shape != RailShape.NORTH_WEST && shape != RailShape.SOUTH_EAST && shape != RailShape.SOUTH_WEST; ++ }).toList(); ++ } ++ return state.setValue(property, ShearsItem.getRelative(possibleValues, state.getValue(property), inverse)); // CraftBukkit - decompile error + } + + private static T getRelative(Iterable elements, T current, boolean inverse) { diff --git a/leaves-server/minecraft-patches/features/0010-Add-isShrink-to-EntityResurrectEvent.patch b/leaves-server/minecraft-patches/features/0010-Add-isShrink-to-EntityResurrectEvent.patch index 50e14445..150b5c91 100644 --- a/leaves-server/minecraft-patches/features/0010-Add-isShrink-to-EntityResurrectEvent.patch +++ b/leaves-server/minecraft-patches/features/0010-Add-isShrink-to-EntityResurrectEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add isShrink to EntityResurrectEvent diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 3e8f4f3c3d43c6875108295187023c48eece2788..5fc4d97ef421a37158b01864b035385bb7bf5f5f 100644 +index 1ba342a1a60951f828034d3ed535b577b3990bf6..7a7971ec03fcdf72ecaa1e934d5ab3c62113c251 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -1701,14 +1701,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1733,14 +1733,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin } final org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null; diff --git a/leaves-server/minecraft-patches/features/0012-Spectator-dont-get-Advancement.patch b/leaves-server/minecraft-patches/features/0012-Spectator-dont-get-Advancement.patch index 364f917c..c7930a34 100644 --- a/leaves-server/minecraft-patches/features/0012-Spectator-dont-get-Advancement.patch +++ b/leaves-server/minecraft-patches/features/0012-Spectator-dont-get-Advancement.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Spectator dont get Advancement diff --git a/net/minecraft/server/PlayerAdvancements.java b/net/minecraft/server/PlayerAdvancements.java -index f56a3fb47aa34c39cbd0e0e4e47d924da1488d7a..82fb9c61ce97c2e88a3252068bb28eb40bda0273 100644 +index 5c0e338dc1b0eb5724d10a73d6fc7975f9d2e5e5..a14401edec04964e6c596c16ba58643b835ef9c1 100644 --- a/net/minecraft/server/PlayerAdvancements.java +++ b/net/minecraft/server/PlayerAdvancements.java -@@ -168,6 +168,11 @@ public class PlayerAdvancements { +@@ -167,6 +167,11 @@ public class PlayerAdvancements { } public boolean award(AdvancementHolder advancement, String criterionKey) { diff --git a/leaves-server/minecraft-patches/features/0013-Stick-can-change-ArmorStand-arm-status.patch b/leaves-server/minecraft-patches/features/0013-Stick-can-change-ArmorStand-arm-status.patch index 7f218e64..5fe1b057 100644 --- a/leaves-server/minecraft-patches/features/0013-Stick-can-change-ArmorStand-arm-status.patch +++ b/leaves-server/minecraft-patches/features/0013-Stick-can-change-ArmorStand-arm-status.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Stick can change ArmorStand arm status diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java -index 6f601a0a300bbf01f77d835576d15e25c8ba10b8..9ef422c34a70367f4dcee50b51a17143d14f131c 100644 +index 46369e554be8c72e6fc2e6d58374dbfc77d94879..d7725b5ca689e3d5b512baab04e113be77c0b2ee 100644 --- a/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -270,6 +270,13 @@ public class ArmorStand extends LivingEntity { +@@ -228,6 +228,13 @@ public class ArmorStand extends LivingEntity { return InteractionResult.SUCCESS_SERVER; } } else { diff --git a/leaves-server/minecraft-patches/features/0015-No-chat-sign.patch b/leaves-server/minecraft-patches/features/0015-No-chat-sign.patch index b1634205..7bcba50f 100644 --- a/leaves-server/minecraft-patches/features/0015-No-chat-sign.patch +++ b/leaves-server/minecraft-patches/features/0015-No-chat-sign.patch @@ -27,25 +27,6 @@ index 47cb25aa9c37bd84d156288c397321009f1d9ae2..a94981882ac37ea215df3a71117d4a9b public void write(FriendlyByteBuf buffer) { buffer.writeCollection(this.entries, (buffer1, entry) -> entry.write(buffer1)); } -diff --git a/net/minecraft/network/FriendlyByteBuf.java b/net/minecraft/network/FriendlyByteBuf.java -index 7da7d645f83f351e8c964da01734f3074a877ca1..a9d37c540397b5e24721b3eba47e2d5b2577579f 100644 ---- a/net/minecraft/network/FriendlyByteBuf.java -+++ b/net/minecraft/network/FriendlyByteBuf.java -@@ -118,6 +118,14 @@ public class FriendlyByteBuf extends ByteBuf { - public void writeJsonWithCodec(Codec codec, T value, int maxLength) { - // Paper end - Adventure; add max length parameter - DataResult dataResult = codec.encodeStart(JsonOps.INSTANCE, value); -+ // Leaves start - no chat sign -+ if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { -+ JsonElement element = dataResult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value)); -+ element.getAsJsonObject().addProperty("preventsChatReports", org.leavesmc.leaves.LeavesConfig.mics.noChatSign); -+ this.writeUtf(GSON.toJson(element)); -+ return; -+ } -+ // Leaves end - no chat sign - this.writeUtf(GSON.toJson(dataResult.getOrThrow(exception -> new EncoderException("Failed to encode: " + exception + " " + value))), maxLength); // Paper - Adventure; add max length parameter - } - diff --git a/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/net/minecraft/network/protocol/game/ServerboundChatPacket.java index b5afc05924ae899e020c303c8b86398e1d4ab8a0..4479634e577913372faf87138b5ba26ba02ea4f7 100644 --- a/net/minecraft/network/protocol/game/ServerboundChatPacket.java @@ -90,11 +71,45 @@ index 1df628ac0b414511aaed6e09d78f884c4170f730..b92081d70ffeec47c304e553ce1aea0a handler.handleChatSessionUpdate(this); } } +diff --git a/net/minecraft/network/protocol/status/ServerStatus.java b/net/minecraft/network/protocol/status/ServerStatus.java +index a491be4250de3199c3e1aa9e5482b568692bd2f5..9844b19020ef6e4fa5a3008dcd768bb674657d2f 100644 +--- a/net/minecraft/network/protocol/status/ServerStatus.java ++++ b/net/minecraft/network/protocol/status/ServerStatus.java +@@ -20,7 +20,8 @@ public record ServerStatus( + Optional players, + Optional version, + Optional favicon, +- boolean enforcesSecureChat ++ boolean enforcesSecureChat, // Leaves - no chat sign ++ boolean preventsChatReports // Leaves - no chat sign + ) { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( +@@ -28,11 +29,18 @@ public record ServerStatus( + ServerStatus.Players.CODEC.lenientOptionalFieldOf("players").forGetter(ServerStatus::players), + ServerStatus.Version.CODEC.lenientOptionalFieldOf("version").forGetter(ServerStatus::version), + ServerStatus.Favicon.CODEC.lenientOptionalFieldOf("favicon").forGetter(ServerStatus::favicon), +- Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", false).forGetter(ServerStatus::enforcesSecureChat) ++ Codec.BOOL.lenientOptionalFieldOf("enforcesSecureChat", false).forGetter(ServerStatus::enforcesSecureChat), // Leaves - no chat sign ++ Codec.BOOL.lenientOptionalFieldOf("preventsChatReports", false).forGetter(ServerStatus::preventsChatReports) // Leaves - no chat sign + ) + .apply(instance, ServerStatus::new) + ); + ++ // Leaves start - no chat sign ++ public ServerStatus(Component description, Optional players, Optional version, Optional favicon, boolean enforcesSecureChat) { ++ this(description, players, version, favicon, enforcesSecureChat, org.leavesmc.leaves.LeavesConfig.mics.noChatSign); ++ } ++ // Leaves end - no chat sign ++ + public record Favicon(byte[] iconBytes) { + private static final String PREFIX = "data:image/png;base64,"; + public static final Codec CODEC = Codec.STRING.comapFlatMap(string -> { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index e56f26fc504538d88bfa1954e929ee44fd31d657..e4946438d0c1fb9d2be616cb95768f890b32f286 100644 +index f85993fc507d699728e058b12bb49dcb7aaea44b..91babab6152bb12768399ef6f2ea6afcb5e644b7 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -574,7 +574,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -573,7 +573,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface // Paper start - Add setting for proxy online mode status return properties.enforceSecureProfile && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() @@ -104,10 +119,10 @@ index e56f26fc504538d88bfa1954e929ee44fd31d657..e4946438d0c1fb9d2be616cb95768f89 } diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index ac5ef04fae4bc19bae9007c0ffd8f688434d22d7..649aeec6954d26cb67827e99c4b5b736f4f5bef4 100644 +index 2dd95aca955f19ce48be35b1ca9bcc94c3a1984d..e9d328dacdc23eea792ab350ec2ea9f8337ae008 100644 --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -294,10 +294,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -322,10 +322,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public void send(Packet packet) { @@ -121,11 +136,11 @@ index ac5ef04fae4bc19bae9007c0ffd8f688434d22d7..649aeec6954d26cb67827e99c4b5b736 this.send(packet, null); } - public void send(Packet packet, @Nullable PacketSendListener listener) { + public void send(Packet packet, @Nullable ChannelFutureListener channelFutureListener) { + // Leaves start - no ClientboundPlayerChatHeaderPacket and rebuild ClientboundPlayerChatPacket + if (org.leavesmc.leaves.LeavesConfig.mics.noChatSign) { -+ if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket && listener != null) { -+ listener = null; ++ if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket && channelFutureListener != null) { ++ channelFutureListener = null; + } + } + // Leaves end - no ClientboundPlayerChatHeaderPacket and rebuild ClientboundPlayerChatPacket @@ -133,10 +148,10 @@ index ac5ef04fae4bc19bae9007c0ffd8f688434d22d7..649aeec6954d26cb67827e99c4b5b736 if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 0cf30681a9e3d68f3abe1d87b9fd4220083685a9..491d7b5a0cc099a3eb658e19cbe9d97b4419382c 100644 +index 204c25d33e86a736f091848a277ea882f129e468..742a49c9f1cec6a7ed343b1f0072fc36bb3df26b 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -1339,7 +1339,7 @@ public abstract class PlayerList { +@@ -1315,7 +1315,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { diff --git a/leaves-server/minecraft-patches/features/0016-Dont-send-useless-entity-packets.patch b/leaves-server/minecraft-patches/features/0016-Dont-send-useless-entity-packets.patch index e042b851..5f580054 100644 --- a/leaves-server/minecraft-patches/features/0016-Dont-send-useless-entity-packets.patch +++ b/leaves-server/minecraft-patches/features/0016-Dont-send-useless-entity-packets.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Dont send useless entity packets This patch is Powered by Purpur(https://github.com/PurpurMC/Purpur) diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954..7681195587d361acf524d09ad3958e628aad73b6 100644 +index e96d4dee14c05f2fa329bfb1588ec795d4e3d730..f6b2d541fdfd11c6ff6033fbf4cd5153796634e3 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java -@@ -196,6 +196,11 @@ public class ServerEntity { +@@ -200,6 +200,11 @@ public class ServerEntity { } else if (flag) { packet = new ClientboundMoveEntityPacket.Rot(this.entity.getId(), b, b1, this.entity.onGround()); flag4 = true; @@ -21,7 +21,7 @@ index b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954..7681195587d361acf524d09ad3958e62 } } else { packet = new ClientboundMoveEntityPacket.PosRot(this.entity.getId(), (short)l, (short)l1, (short)l2, b, b1, this.entity.onGround()); -@@ -315,6 +320,21 @@ public class ServerEntity { +@@ -319,6 +324,21 @@ public class ServerEntity { this.positionCodec.setBase(this.entity.position()); } diff --git a/leaves-server/minecraft-patches/features/0017-Optimize-suffocation.patch b/leaves-server/minecraft-patches/features/0017-Optimize-suffocation.patch index 16211a72..731a9247 100644 --- a/leaves-server/minecraft-patches/features/0017-Optimize-suffocation.patch +++ b/leaves-server/minecraft-patches/features/0017-Optimize-suffocation.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize suffocation This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 5fc4d97ef421a37158b01864b035385bb7bf5f5f..b5f6a76c977bbb5dbb06fb3dd654f0b01aaba692 100644 +index 7a7971ec03fcdf72ecaa1e934d5ab3c62113c251..f0ff74a4f2831ead191bc12cb4873162a470c71f 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -423,7 +423,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -437,7 +437,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin if (this.isAlive() && this.level() instanceof ServerLevel serverLevel1) { boolean flag = this instanceof Player; @@ -18,7 +18,7 @@ index 5fc4d97ef421a37158b01864b035385bb7bf5f5f..b5f6a76c977bbb5dbb06fb3dd654f0b0 this.hurtServer(serverLevel1, this.damageSources().inWall(), 1.0F); } else if (flag && !serverLevel1.getWorldBorder().isWithinBounds(this.getBoundingBox())) { double d = serverLevel1.getWorldBorder().getDistanceToBorder(this) + serverLevel1.getWorldBorder().getDamageSafeZone(); -@@ -1372,6 +1372,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1404,6 +1404,12 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin return this.getHealth() <= 0.0F; } diff --git a/leaves-server/minecraft-patches/features/0018-Only-check-for-spooky-season-once-an-hour.patch b/leaves-server/minecraft-patches/features/0018-Only-check-for-spooky-season-once-an-hour.patch index 13e39bd9..fded8ce8 100644 --- a/leaves-server/minecraft-patches/features/0018-Only-check-for-spooky-season-once-an-hour.patch +++ b/leaves-server/minecraft-patches/features/0018-Only-check-for-spooky-season-once-an-hour.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Only check for spooky season once an hour This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/net/minecraft/world/entity/ambient/Bat.java b/net/minecraft/world/entity/ambient/Bat.java -index eb9fb57440f498079182030a46034008d3f6b5e8..5f0ddf96e8ca1bb32c773f11232dedd1a981fde9 100644 +index 912b099a51269f92f250c7d6094ad41817749f93..af661d572d2bab00a392f858dd910c8be5e16e81 100644 --- a/net/minecraft/world/entity/ambient/Bat.java +++ b/net/minecraft/world/entity/ambient/Bat.java -@@ -244,12 +244,30 @@ public class Bat extends AmbientCreature { +@@ -245,12 +245,30 @@ public class Bat extends AmbientCreature { } } diff --git a/leaves-server/minecraft-patches/features/0019-Config-to-disable-method-profiler.patch b/leaves-server/minecraft-patches/features/0019-Config-to-disable-method-profiler.patch index 3f69e9d2..4a65a666 100644 --- a/leaves-server/minecraft-patches/features/0019-Config-to-disable-method-profiler.patch +++ b/leaves-server/minecraft-patches/features/0019-Config-to-disable-method-profiler.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Config to disable method profiler This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 940e6cb4b8f990e3c4ae8a5efc7adc56ffae28de..105c207b8db2c505f256f4104642af5929b50aa9 100644 +index feb5fc93498a5ed89e3bcb61cd72ba6e75881358..6539574b72dcb362d8d106a68d6e2d968340fc5e 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1247,7 +1247,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, AutoCl diff --git a/leaves-server/minecraft-patches/features/0027-BBOR-Protocol.patch b/leaves-server/minecraft-patches/features/0027-BBOR-Protocol.patch index 51256fda..68b359b4 100644 --- a/leaves-server/minecraft-patches/features/0027-BBOR-Protocol.patch +++ b/leaves-server/minecraft-patches/features/0027-BBOR-Protocol.patch @@ -5,10 +5,10 @@ Subject: [PATCH] BBOR Protocol diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 5d3fc807221392d378fec283bfdefb8747fb8376..bf731da711ce629c0f9250a7bd4025d363623773 100644 +index 75578e6ed7233a03d9b6cd3c6d3997f1c6148392..f24db919989bc2e5768e18b4fda68c38d6cde7e0 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -743,6 +743,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -749,6 +749,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p public void setLoaded(boolean loaded) { this.loaded = loaded; diff --git a/leaves-server/minecraft-patches/features/0028-PCA-sync-protocol.patch b/leaves-server/minecraft-patches/features/0028-PCA-sync-protocol.patch index 97714888..d17a0820 100644 --- a/leaves-server/minecraft-patches/features/0028-PCA-sync-protocol.patch +++ b/leaves-server/minecraft-patches/features/0028-PCA-sync-protocol.patch @@ -6,10 +6,10 @@ Subject: [PATCH] PCA sync protocol This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) diff --git a/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/net/minecraft/world/entity/animal/horse/AbstractHorse.java -index 7c473eea481f5e055cc70512027726f41f0c6f67..3165d1eaa46f2adceba28d4aef95fda3f05ee5e3 100644 +index 31ed5d7cfbda1a1f98ebfc89f5cbc65332cabdae..18c683f7d7e18200a24cfc8d26e83f578681f7f5 100644 --- a/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -303,6 +303,13 @@ public abstract class AbstractHorse extends Animal implements HasCustomInventory +@@ -305,6 +305,13 @@ public abstract class AbstractHorse extends Animal implements HasCustomInventory public void createInventory() { SimpleContainer simpleContainer = this.inventory; this.inventory = new SimpleContainer(this.getInventorySize(), (org.bukkit.entity.AbstractHorse) this.getBukkitEntity()); // CraftBukkit @@ -24,7 +24,7 @@ index 7c473eea481f5e055cc70512027726f41f0c6f67..3165d1eaa46f2adceba28d4aef95fda3 int min = Math.min(simpleContainer.getContainerSize(), this.inventory.getContainerSize()); diff --git a/net/minecraft/world/entity/npc/AbstractVillager.java b/net/minecraft/world/entity/npc/AbstractVillager.java -index 1d3381f1481bb2b192bb78462c85c2a185d94ad5..a375fad192cc09ba83775d5e37c1bb351730e6c4 100644 +index f8782cdcf3015cad2693663a3c222bd60822f45b..38572ecba568072b132b9e7fc12e6c0c38edd2e2 100644 --- a/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/net/minecraft/world/entity/npc/AbstractVillager.java @@ -48,6 +48,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -44,10 +44,10 @@ index 1d3381f1481bb2b192bb78462c85c2a185d94ad5..a375fad192cc09ba83775d5e37c1bb35 @Override diff --git a/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -index a7e2f23ed3279801504f99fc3c5f972e8c1b984f..4509b1a68273effa30d1befafc9104220d02fe8b 100644 +index 6a008c86f4e360c916b93f0e3a62a9d8b43e74e6..7781ca07a0c8fe1140f341b695e66de95802ee2e 100644 --- a/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -64,6 +64,11 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme +@@ -65,6 +65,11 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme @Override public void setChanged() { @@ -60,7 +60,7 @@ index a7e2f23ed3279801504f99fc3c5f972e8c1b984f..4509b1a68273effa30d1befafc910422 @Override diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index c5b3b5e5f621f8db152aa190374ae0fe567d6828..7729c33cad94cf2b4162324be75713650fc9d378 100644 +index 36a72a11d28f99bfe85868461925b778cc01478e..bebe8737b71fc37336342f14b6ea4cfab12d3f34 100644 --- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -429,6 +429,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit @@ -81,7 +81,7 @@ index c5b3b5e5f621f8db152aa190374ae0fe567d6828..7729c33cad94cf2b4162324be7571365 public void setRecipeUsed(@Nullable RecipeHolder recipe) { if (recipe != null) { diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java -index 027502d0af5512c31878978c4d05c52fa3029cca..b3da250aa326d05a4e95c7b749c8ae8975dfd804 100644 +index d679ab599dfd0bdbdc3ab5530d7fcd1c38baf7fa..f0ba09c0edc598dfc4e501ba69016e8a2f8d3a7c 100644 --- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java @@ -121,6 +121,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { @@ -102,10 +102,10 @@ index 027502d0af5512c31878978c4d05c52fa3029cca..b3da250aa326d05a4e95c7b749c8ae89 protected Component getDefaultName() { return Component.translatable("container.barrel"); diff --git a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -index 331eb5416307378162e39e20192ba06a047b70ea..69419e74c308e46509cc40fde9ed05583964a1ca 100644 +index 91f7ee163107d846e7f6a5783be6eff96e783886..cbbe3dee3dda06d0e2451597dae0ac03009330e0 100644 --- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -144,6 +144,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -147,6 +147,11 @@ public class BeehiveBlockEntity extends BlockEntity { super.setChanged(); } @@ -117,7 +117,7 @@ index 331eb5416307378162e39e20192ba06a047b70ea..69419e74c308e46509cc40fde9ed0558 return list; } -@@ -201,6 +206,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -204,6 +209,11 @@ public class BeehiveBlockEntity extends BlockEntity { this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(bee, this.getBlockState())); } @@ -129,7 +129,7 @@ index 331eb5416307378162e39e20192ba06a047b70ea..69419e74c308e46509cc40fde9ed0558 bee.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.ENTER_BLOCK); // CraftBukkit - add Bukkit remove cause super.setChanged(); } -@@ -322,6 +332,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -325,6 +335,11 @@ public class BeehiveBlockEntity extends BlockEntity { if (releaseOccupant(level, pos, state, beeData.toOccupant(), null, beeReleaseStatus, savedFlowerPos)) { flag = true; iterator.remove(); @@ -141,10 +141,10 @@ index 331eb5416307378162e39e20192ba06a047b70ea..69419e74c308e46509cc40fde9ed0558 } // Paper start - Fix bees aging inside; use exitTickCounter to keep actual bee life else if (level.paperConfig().entities.behavior.cooldownFailedBeehiveReleases) { -@@ -355,6 +370,11 @@ public class BeehiveBlockEntity extends BlockEntity { - tag.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee); - this.savedFlowerPos = tag.read("flower_pos", BlockPos.CODEC).orElse(null); - this.maxBees = tag.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants +@@ -358,6 +373,11 @@ public class BeehiveBlockEntity extends BlockEntity { + input.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee); + this.savedFlowerPos = input.read("flower_pos", BlockPos.CODEC).orElse(null); + this.maxBees = input.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants + // Leaves start - pca + if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); @@ -154,7 +154,7 @@ index 331eb5416307378162e39e20192ba06a047b70ea..69419e74c308e46509cc40fde9ed0558 @Override diff --git a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java -index 2e369167d4d1664df1f0b375597bb12b728c5c62..e13a2845efc88bd68ee96cbc1b58bf4f7fb77845 100644 +index 79a9f1c87de30cda479b55cf70fbc3219a3dcad4..7eac2188a38fff2ecfa4082b5d023b111cf7d8f6 100644 --- a/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java @@ -331,4 +331,14 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements @@ -173,7 +173,7 @@ index 2e369167d4d1664df1f0b375597bb12b728c5c62..e13a2845efc88bd68ee96cbc1b58bf4f + // Leaves end - pca } diff --git a/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/net/minecraft/world/level/block/entity/ChestBlockEntity.java -index a7a095cc0ffdf7b0daf7b4d19c3e78bc4399fa7c..faac046a95a7db5f5fd456bd8f768b0aaab1db5e 100644 +index b7d94ebe0ee995392c355c4237da8443dcc79b21..784e146b28370dc2dac094d5f2ac654a5bc47e01 100644 --- a/net/minecraft/world/level/block/entity/ChestBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ChestBlockEntity.java @@ -202,6 +202,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement @@ -194,11 +194,11 @@ index a7a095cc0ffdf7b0daf7b4d19c3e78bc4399fa7c..faac046a95a7db5f5fd456bd8f768b0a protected AbstractContainerMenu createMenu(int id, Inventory player) { return ChestMenu.threeRows(id, player, this); diff --git a/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java b/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java -index d0119f3df52fe26c85d8b67ee59e24adf7b427ac..18ff2cd322168f57f3a1b3b4c0e9a02560cb9965 100644 +index 6b5179ae4269829b1e356840c9a8c33153334c32..b78ee57634471bc6e5308fb30c8f974fdce516de 100644 --- a/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java @@ -25,6 +25,16 @@ public class ComparatorBlockEntity extends BlockEntity { - this.output = tag.getIntOr("OutputSignal", 0); + this.output = input.getIntOr("OutputSignal", 0); } + // Leaves start - pca @@ -215,7 +215,7 @@ index d0119f3df52fe26c85d8b67ee59e24adf7b427ac..18ff2cd322168f57f3a1b3b4c0e9a025 return this.output; } diff --git a/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/net/minecraft/world/level/block/entity/DispenserBlockEntity.java -index 3fb7a7b9f182062ebed778e7bb9ba239ae9f179c..a8256fd0d14655fe480b6e04ce32814e54f9d9c6 100644 +index ae52dc75335799e55e403e3d3f11e9f1d67e4305..36b9362e1ce31b63c100ec65921e095fb7871e82 100644 --- a/net/minecraft/world/level/block/entity/DispenserBlockEntity.java +++ b/net/minecraft/world/level/block/entity/DispenserBlockEntity.java @@ -104,6 +104,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity { @@ -236,7 +236,7 @@ index 3fb7a7b9f182062ebed778e7bb9ba239ae9f179c..a8256fd0d14655fe480b6e04ce32814e protected Component getDefaultName() { return Component.translatable("container.dispenser"); diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 15d4f60942c0cc612c1468b4c0fda886867a67cb..212a1a1410550a2456a88a948f377048447a1fc8 100644 +index 800b7e78ae989868ed0b9e060c80dcd002759412..5f42af7c6fc82d6672ed06a2315254c9c5886ce4 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -122,6 +122,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -269,7 +269,7 @@ index 15d4f60942c0cc612c1468b4c0fda886867a67cb..212a1a1410550a2456a88a948f377048 } } diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index 87ebdb6deb66662a38b3eec0dae27eaf859ecabb..5e58113b3401268e0432235dc10b2734dbbd8b71 100644 +index ebea67223ce1d350087c73dff0cc3fe6d7b47ca0..a820ab9a2b6dc6b95d4de61aaaad4e79c521efe4 100644 --- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java @@ -267,6 +267,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl diff --git a/leaves-server/minecraft-patches/features/0029-Alternative-block-placement-Protocol.patch b/leaves-server/minecraft-patches/features/0029-Alternative-block-placement-Protocol.patch index 5485cb1e..89a56f14 100644 --- a/leaves-server/minecraft-patches/features/0029-Alternative-block-placement-Protocol.patch +++ b/leaves-server/minecraft-patches/features/0029-Alternative-block-placement-Protocol.patch @@ -9,10 +9,10 @@ MasaGadget(https://github.com/plusls/MasaGadget) litematica(https://github.com/maruohon/litematica) diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java -index 2fbbbac9f1472354bd507926a85c25f48291edfe..98c94e0957933828be79e6326d782af6aa738dd9 100644 +index 6db566adf2d0df1d26221eda04aa01738df6d3d2..14387fa191fb52aaa8b25396292c1d528a6aed17 100644 --- a/net/minecraft/world/item/BlockItem.java +++ b/net/minecraft/world/item/BlockItem.java -@@ -151,6 +151,27 @@ public class BlockItem extends Item { +@@ -150,6 +150,27 @@ public class BlockItem extends Item { @Nullable protected BlockState getPlacementState(BlockPlaceContext context) { BlockState stateForPlacement = this.getBlock().getStateForPlacement(context); @@ -62,7 +62,7 @@ index 12c6c8aeec89a0a55633c62fe98f5a3aa75fd476..1f0e7c391d02b18e2c89700025713ec3 blockState = blockState1; break; diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java -index f289e37f77e1c9d3b0f6c29da1b99f0d5f156e37..848409f44e766ce2a5b74563bf2fd4a6b5d63d33 100644 +index 958914e40fceda5d67a98154817b4c5ce478a62d..02ea7616e0c19032374959f59a9ab186e91c5f7b 100644 --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java @@ -439,6 +439,33 @@ public class Block extends BlockBehaviour implements ItemLike { diff --git a/leaves-server/minecraft-patches/features/0030-Jade-Protocol.patch b/leaves-server/minecraft-patches/features/0030-Jade-Protocol.patch index cbf25c5e..01b6bbda 100644 --- a/leaves-server/minecraft-patches/features/0030-Jade-Protocol.patch +++ b/leaves-server/minecraft-patches/features/0030-Jade-Protocol.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Jade Protocol This patch is Powered by Jade(https://github.com/Snownee/Jade) diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -index b72e07ad954efa7f26f876a59f428086b40d9bb2..102746fc84ca9c8899db971fc1490060ea016b7e 100644 +index c1798db2972c8f2a343cf6e16fd9354ff212d906..a8d617b16ab2b2c0cdb289a0aa05fa171940cd7e 100644 --- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -62,7 +62,7 @@ public class Armadillo extends Animal { +@@ -63,7 +63,7 @@ public class Armadillo extends Animal { public final AnimationState rollOutAnimationState = new AnimationState(); public final AnimationState rollUpAnimationState = new AnimationState(); public final AnimationState peekAnimationState = new AnimationState(); @@ -19,10 +19,10 @@ index b72e07ad954efa7f26f876a59f428086b40d9bb2..102746fc84ca9c8899db971fc1490060 public Armadillo(EntityType entityType, Level level) { diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java -index ebdfd3fb6c0de48982d392bb2aa415f3676c6056..9d5acb2559143358b1258cbb674191bdddb331e3 100644 +index 17f58246849ed407821a987b200cc765eb7943f9..ac27df3ba0ce9bbdf2f32ea87171fbb9407008d6 100644 --- a/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -252,7 +252,7 @@ public class Tadpole extends AbstractFish { +@@ -254,7 +254,7 @@ public class Tadpole extends AbstractFish { } } @@ -32,10 +32,10 @@ index ebdfd3fb6c0de48982d392bb2aa415f3676c6056..9d5acb2559143358b1258cbb674191bd } diff --git a/net/minecraft/world/level/storage/loot/LootPool.java b/net/minecraft/world/level/storage/loot/LootPool.java -index 29ad43245a310756c4227acd7532e905f7f8b8ee..ad422817593449b8e914628b51d760e732e2d50c 100644 +index 6901e629d941e22e64d83eed4e8cfee3165a96a1..fdc26c8d8c82c20534c57af2a0281b99998cc9f6 100644 --- a/net/minecraft/world/level/storage/loot/LootPool.java +++ b/net/minecraft/world/level/storage/loot/LootPool.java -@@ -36,7 +36,7 @@ public class LootPool { +@@ -37,7 +37,7 @@ public class LootPool { ) .apply(instance, LootPool::new) ); @@ -45,10 +45,10 @@ index 29ad43245a310756c4227acd7532e905f7f8b8ee..ad422817593449b8e914628b51d760e7 private final Predicate compositeCondition; private final List functions; diff --git a/net/minecraft/world/level/storage/loot/LootTable.java b/net/minecraft/world/level/storage/loot/LootTable.java -index 7a8eb1e8b07647e1124594f78652d34731e4fda6..6cfe7ef8c81f506bce9c971b597cc4e902bcabbe 100644 +index 8612cdf7161f8ddff60a6478cc901318b8f958ba..07a962d647baa99b0e1bf3898a07cc914e91397e 100644 --- a/net/minecraft/world/level/storage/loot/LootTable.java +++ b/net/minecraft/world/level/storage/loot/LootTable.java -@@ -49,7 +49,7 @@ public class LootTable { +@@ -50,7 +50,7 @@ public class LootTable { public static final LootTable EMPTY = new LootTable(LootContextParamSets.EMPTY, Optional.empty(), List.of(), List.of()); private final ContextKeySet paramSet; private final Optional randomSequence; @@ -58,23 +58,23 @@ index 7a8eb1e8b07647e1124594f78652d34731e4fda6..6cfe7ef8c81f506bce9c971b597cc4e9 private final BiFunction compositeFunction; public org.bukkit.craftbukkit.CraftLootTable craftLootTable; // CraftBukkit diff --git a/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java b/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java -index 8e91ddc6c0e492d165ad8322b4a3d5c3bad5409c..6e420bfb3c223b094157bdfec7dad20d8eab4968 100644 +index eeaa49e9f70a18b5d39493aeff73f31b05ac2faa..8cd0403d7873c4c37caef75935b06b056c3d951d 100644 --- a/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java +++ b/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java -@@ -9,7 +9,7 @@ import net.minecraft.world.level.storage.loot.ValidationContext; - import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; - - public abstract class CompositeEntryBase extends LootPoolEntryContainer { +@@ -16,7 +16,7 @@ public abstract class CompositeEntryBase extends LootPoolEntryContainer { + return "Empty children list"; + } + }; - protected final List children; + public final List children; // Leaves - private -> public private final ComposableEntryContainer composedChildren; protected CompositeEntryBase(List children, List conditions) { diff --git a/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java b/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java -index e0e933245e038b7229eeddbda272b081161ab603..c5e3834fa970ac909cefea43420378394153d781 100644 +index 65e27bce9e59ef97bc8b914d646fba924d0f0877..a49bdcdf37b351436e0ba6d7865f10827c4e6ab4 100644 --- a/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java +++ b/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java -@@ -13,7 +13,7 @@ import net.minecraft.world.level.storage.loot.predicates.ConditionUserBuilder; +@@ -14,7 +14,7 @@ import net.minecraft.world.level.storage.loot.predicates.ConditionUserBuilder; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; public abstract class LootPoolEntryContainer implements ComposableEntryContainer { @@ -84,23 +84,23 @@ index e0e933245e038b7229eeddbda272b081161ab603..c5e3834fa970ac909cefea4342037839 protected LootPoolEntryContainer(List conditions) { diff --git a/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java b/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java -index f7b647e81ca99040bae8161a2bc0dcacf5bd537f..069df530b1db72bd4a2b1b80b2570dca545dfd20 100644 +index 141026601cd9a4561426b85fd1f8e7dc0544fbd7..a5d7ebb93c147bf0f806ac3c9b2dc4b878573944 100644 --- a/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java +++ b/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java -@@ -22,7 +22,7 @@ public class NestedLootTable extends LootPoolSingletonContainer { - .and(singletonFields(instance)) - .apply(instance, NestedLootTable::new) - ); +@@ -29,7 +29,7 @@ public class NestedLootTable extends LootPoolSingletonContainer { + return "->{inline}"; + } + }; - private final Either, LootTable> contents; + public final Either, LootTable> contents; // Leaves - private -> public private NestedLootTable( Either, LootTable> contents, int weight, int quality, List conditions, List functions diff --git a/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java b/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java -index 7134c54984a12949cd6a2e8dc35c2e1c0431e524..52f36fbb9bfcad81004e531efab85e9b87d3284d 100644 +index bae72197acc929c7ed3e964f156115d728eb2176..8f3094f42f3366a1313d70c0b27fbe5632b2082a 100644 --- a/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java +++ b/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java -@@ -11,7 +11,7 @@ import net.minecraft.world.level.storage.loot.LootContext; +@@ -12,7 +12,7 @@ import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.ValidationContext; public abstract class CompositeLootItemCondition implements LootItemCondition { diff --git a/leaves-server/minecraft-patches/features/0031-Player-operation-limiter.patch b/leaves-server/minecraft-patches/features/0031-Player-operation-limiter.patch index 6204cd0b..01d9e754 100644 --- a/leaves-server/minecraft-patches/features/0031-Player-operation-limiter.patch +++ b/leaves-server/minecraft-patches/features/0031-Player-operation-limiter.patch @@ -6,12 +6,12 @@ Subject: [PATCH] Player operation limiter This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 01687ea3acf449c49cbc615887a7dbdd3a693613..988992a181e35a3856817419cb4941c73a9c31f2 100644 +index 7e4bf7ddc26fc087832f802856f14e268b0ca32b..1b9a5e8b061371649cbd464d1167c2e99e6494bc 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -420,6 +420,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -429,6 +429,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + public boolean isRealPlayer; // Paper public @Nullable com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent - public @Nullable String clientBrandName = null; // Paper - Brand support public @Nullable org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event + // Leaves start - player operation limiter + private int instaBreakCountPerTick = 0; @@ -20,7 +20,7 @@ index 01687ea3acf449c49cbc615887a7dbdd3a693613..988992a181e35a3856817419cb4941c7 // Paper start - rewrite chunk system private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; -@@ -744,6 +748,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -745,6 +749,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } // CraftBukkit end this.tickClientLoadTimeout(); @@ -28,7 +28,7 @@ index 01687ea3acf449c49cbc615887a7dbdd3a693613..988992a181e35a3856817419cb4941c7 this.gameMode.tick(); this.wardenSpawnTracker.tick(); if (this.invulnerableTime > 0) { -@@ -2933,4 +2938,31 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -2977,4 +2982,31 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end @@ -61,7 +61,7 @@ index 01687ea3acf449c49cbc615887a7dbdd3a693613..988992a181e35a3856817419cb4941c7 + // Leaves end - player operation limiter } diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java -index b604cba2490a747661d6819251bc3b9a1d35c7d4..5e54d6de0430cd137fbe13ca8f17dc487ce52ff3 100644 +index cfbf34964288526e93d0a5b212c1b60296c10430..9cce442c16ced8d9320a5760580ff13f02cbf8f1 100644 --- a/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/net/minecraft/server/level/ServerPlayerGameMode.java @@ -300,6 +300,19 @@ public class ServerPlayerGameMode { @@ -85,7 +85,7 @@ index b604cba2490a747661d6819251bc3b9a1d35c7d4..5e54d6de0430cd137fbe13ca8f17dc48 this.debugLogging(pos, true, sequence, message); } else { diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java -index 3f58574069f22d83298a77f253255b25724890ad..0c67e5481a43bf7c02bb54a8ea1abca77d53a292 100644 +index 14387fa191fb52aaa8b25396292c1d528a6aed17..eff2c0418e1dc8dff1b9045d8f6ff619100964d1 100644 --- a/net/minecraft/world/item/BlockItem.java +++ b/net/minecraft/world/item/BlockItem.java @@ -65,6 +65,21 @@ public class BlockItem extends Item { diff --git a/leaves-server/minecraft-patches/features/0032-Renewable-Elytra.patch b/leaves-server/minecraft-patches/features/0032-Renewable-Elytra.patch index 5e528c3d..6b913faf 100644 --- a/leaves-server/minecraft-patches/features/0032-Renewable-Elytra.patch +++ b/leaves-server/minecraft-patches/features/0032-Renewable-Elytra.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Renewable Elytra This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 483b0499f1f70b3aa8862e6cd8e512748492bee0..5467a1b28525386dfae2a04d8c69d23f163c74f5 100644 +index ffcfdbc80df2a9e6c546348b86e7615e6109eb49..d985f224f06f5a823f74b276477ededdbe77596a 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -231,6 +231,20 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -246,6 +246,20 @@ public class Phantom extends Mob implements Enemy { return targetingConditions.test(level, this, entity); } diff --git a/leaves-server/minecraft-patches/features/0033-MC-Technical-Survival-Mode.patch b/leaves-server/minecraft-patches/features/0033-MC-Technical-Survival-Mode.patch index 207dd868..2fbf1712 100644 --- a/leaves-server/minecraft-patches/features/0033-MC-Technical-Survival-Mode.patch +++ b/leaves-server/minecraft-patches/features/0033-MC-Technical-Survival-Mode.patch @@ -6,10 +6,10 @@ Subject: [PATCH] MC Technical Survival Mode Will automatically overwrite some configuration after startup diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 988992a181e35a3856817419cb4941c73a9c31f2..66110486725de7967e55839043b9fc9690e4c0f5 100644 +index 1b9a5e8b061371649cbd464d1167c2e99e6494bc..c6adc1009df62699264d996a6eba85d7db4d3bcf 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1614,7 +1614,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1650,7 +1650,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc public boolean isInvulnerableTo(ServerLevel level, DamageSource damageSource) { return (super.isInvulnerableTo(level, damageSource) // Paper - disable player cramming; || this.isChangingDimension() && !damageSource.is(DamageTypes.ENDER_PEARL) @@ -19,10 +19,10 @@ index 988992a181e35a3856817419cb4941c73a9c31f2..66110486725de7967e55839043b9fc96 @Override diff --git a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -index d813427cf20117014bc42af0eb7cdee037fbcd9c..35f8644a9b4704363f6fe1ca19135566a45ef835 100644 +index a0e0fad40838fa7d835f31e5ce4ae3ab40e0bfa4..d8effc3a9773d29319b8e2bd15abbf03f0996ce5 100644 --- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -@@ -64,7 +64,7 @@ public class EndCrystal extends Entity { +@@ -65,7 +65,7 @@ public class EndCrystal extends Entity { } // Paper start - Fix invulnerable end crystals @@ -32,10 +32,10 @@ index d813427cf20117014bc42af0eb7cdee037fbcd9c..35f8644a9b4704363f6fe1ca19135566 || ((ServerLevel) this.level()).getDragonFight() == null || ((ServerLevel) this.level()).getDragonFight().respawnStage == null diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java -index 5d23d8754b304d5e2fd54400cc81c7fe5c14a804..0f28b1befd42a85ffa5462e86d5cde142f9d1196 100644 +index 17d54d38dcec39eefeb989cd576cc640a36e82f5..1d7a1739d6a3a55aacb33d57a58712350b150f64 100644 --- a/net/minecraft/world/entity/item/PrimedTnt.java +++ b/net/minecraft/world/entity/item/PrimedTnt.java -@@ -101,7 +101,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -100,7 +100,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { @Override public void tick() { @@ -58,7 +58,7 @@ index 14a2514a408a66a83f7b5fb43b4c4dc8f23fd5f4..5427f5e1f0416a8dfa3e9c38c3ce69d6 entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) { continue; diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 212a1a1410550a2456a88a948f377048447a1fc8..2d979850378c05ce569782d8e04a452f986612a7 100644 +index 5f42af7c6fc82d6672ed06a2315254c9c5886ce4..e53b40c70c0a61cbe14a236a99725daa28512b0b 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -275,7 +275,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen diff --git a/leaves-server/minecraft-patches/features/0034-Stackable-ShulkerBoxes.patch b/leaves-server/minecraft-patches/features/0034-Item-overstack-util.patch similarity index 66% rename from leaves-server/minecraft-patches/features/0034-Stackable-ShulkerBoxes.patch rename to leaves-server/minecraft-patches/features/0034-Item-overstack-util.patch index 0c56ec9c..e2fb580b 100644 --- a/leaves-server/minecraft-patches/features/0034-Stackable-ShulkerBoxes.patch +++ b/leaves-server/minecraft-patches/features/0034-Item-overstack-util.patch @@ -1,12 +1,12 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Wed, 14 Dec 2022 14:47:06 +0800 -Subject: [PATCH] Stackable ShulkerBoxes +Subject: [PATCH] Item overstack util This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) and plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) diff --git a/net/minecraft/commands/arguments/item/ItemInput.java b/net/minecraft/commands/arguments/item/ItemInput.java -index 643797124fe5a4489d0b7419b7e600c04f283ef2..51971a4ef18ab048dc576c26652982d57e440dc0 100644 +index 643797124fe5a4489d0b7419b7e600c04f283ef2..04b4100da96aad50f08e8c59200eec934e7e873d 100644 --- a/net/minecraft/commands/arguments/item/ItemInput.java +++ b/net/minecraft/commands/arguments/item/ItemInput.java @@ -39,11 +39,13 @@ public class ItemInput { @@ -15,95 +15,95 @@ index 643797124fe5a4489d0b7419b7e600c04f283ef2..51971a4ef18ab048dc576c26652982d5 itemStack.applyComponents(this.components); - if (allowOversizedStacks && count > itemStack.getMaxStackSize()) { - throw ERROR_STACK_TOO_BIG.create(this.getItemName(), itemStack.getMaxStackSize()); -+ // Leaves start - stackable shulker boxes -+ if (allowOversizedStacks && count > org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack)) { -+ throw ERROR_STACK_TOO_BIG.create(this.getItemName(), org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack)); ++ // Leaves start - item over-stack util ++ if (allowOversizedStacks && count > org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)) { ++ throw ERROR_STACK_TOO_BIG.create(this.getItemName(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack)); } else { return itemStack; } -+ // Leaves end - stackable shulker boxes ++ // Leaves end - item over-stack util } public String serialize(HolderLookup.Provider levelRegistry) { diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java -index b81f98738ef166336e4cc3092b6ba63f385b68e3..e800abc1149db77bc9b7ee1aabd17526ebda377c 100644 +index adba92a9ebef64561147427d1339f70e2701d93c..fc367026ca84b125bf3ccd261ef43a3833c1da5c 100644 --- a/net/minecraft/server/commands/GiveCommand.java +++ b/net/minecraft/server/commands/GiveCommand.java -@@ -52,7 +52,7 @@ public class GiveCommand { +@@ -55,7 +55,7 @@ public class GiveCommand { private static int giveItem(CommandSourceStack source, ItemInput item, Collection targets, int count) throws CommandSyntaxException { ItemStack itemStack = item.createItemStack(1, false); final Component displayName = itemStack.getDisplayName(); // Paper - get display name early - int maxStackSize = itemStack.getMaxStackSize(); -+ int maxStackSize = org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack); // Leaves - stackable shulker boxes ++ int maxStackSize = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util int i = maxStackSize * 100; if (count > i) { source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName())); diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 9041830c19e2899479e1519488faba5c416ccd88..ca814ebdb05ca3af138bf087f26d2cf50baf3b9c 100644 +index e6a1dfb9a9f60791457b86d20e86fab8cca79c39..6622d11f970def6adc2a732187004413a9501c95 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2974,7 +2974,7 @@ public class ServerGamePacketListenerImpl +@@ -2986,7 +2986,7 @@ public class ServerGamePacketListenerImpl } else if (slot.mayPlace(cursor)) { if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) { int toPlace = packet.buttonNum() == 0 ? cursor.getCount() : 1; - toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.getCount()); -+ toPlace = Math.min(toPlace, org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(clickedItem) - clickedItem.getCount()); // Leaves - stackable shulker boxes ++ toPlace = Math.min(toPlace, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(clickedItem) - clickedItem.getCount()); // Leaves - item over-stack util toPlace = Math.min(toPlace, slot.container.getMaxStackSize() - clickedItem.getCount()); if (toPlace == 1) { action = InventoryAction.PLACE_ONE; -@@ -3010,7 +3010,7 @@ public class ServerGamePacketListenerImpl +@@ -3022,7 +3022,7 @@ public class ServerGamePacketListenerImpl } } else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) { if (clickedItem.getCount() >= 0) { - if (clickedItem.getCount() + cursor.getCount() <= cursor.getMaxStackSize()) { -+ if (clickedItem.getCount() + cursor.getCount() <= org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(cursor)) { // Leaves - stackable shulker boxes ++ if (clickedItem.getCount() + cursor.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(cursor)) { // Leaves - item over-stack util // As of 1.5, this is result slots only action = InventoryAction.PICKUP_ALL; } -@@ -3269,6 +3269,7 @@ public class ServerGamePacketListenerImpl +@@ -3233,6 +3233,7 @@ public class ServerGamePacketListenerImpl this.player.containerMenu.broadcastFullState(); } else { this.player.containerMenu.broadcastChanges(); -+ if (org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize > 1) this.player.containerMenu.broadcastCarriedItem(); // Leaves - stackable shulker boxes - force send carried item ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.broadcastCarriedItem(); // Leaves - item over-stack util - force send carried item } if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. } -@@ -3381,7 +3382,7 @@ public class ServerGamePacketListenerImpl +@@ -3343,7 +3344,7 @@ public class ServerGamePacketListenerImpl } boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; - boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize(); -+ boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack); // Leaves - stackable shulker boxes ++ boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packet.slotNum()).getItem(), packet.itemStack()))) { // Insist on valid slot // CraftBukkit start - Call click event org.bukkit.inventory.InventoryView inventory = this.player.inventoryMenu.getBukkitView(); -@@ -3423,6 +3424,7 @@ public class ServerGamePacketListenerImpl +@@ -3385,6 +3386,7 @@ public class ServerGamePacketListenerImpl this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack); this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack); this.player.inventoryMenu.broadcastChanges(); -+ if (org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize > 1) this.player.containerMenu.sendSingleSlot(packet.slotNum(), itemStack); // Leaves - stackable shulker boxes - force send carried item ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.hasOverstackingItem()) this.player.containerMenu.sendSingleSlot(packet.slotNum(), itemStack); // Leaves - item over-stack util - force send carried item if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. } else if (flag && flag2) { if (this.dropSpamThrottler.isUnderThreshold()) { diff --git a/net/minecraft/world/Container.java b/net/minecraft/world/Container.java -index b382665cc125b8b5c0938e5e55984e4bf91d37ff..f575b464a8ce430646cb872ae6206a9a0677736b 100644 +index b382665cc125b8b5c0938e5e55984e4bf91d37ff..86cac164a2bf0e76528396e6aabbfd64cfc29559 100644 --- a/net/minecraft/world/Container.java +++ b/net/minecraft/world/Container.java @@ -32,6 +32,12 @@ public interface Container extends Clearable, Iterable { return Math.min(this.getMaxStackSize(), stack.getMaxStackSize()); } -+ // Leaves start - stackable shulker boxes ++ // Leaves start - item over-stack util + default int getMaxStackLeaves(ItemStack stack) { -+ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack)); ++ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); + } -+ // Leaves end - stackable shulker boxes ++ // Leaves end - item over-stack util + void setChanged(); boolean stillValid(Player player); diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java -index 133e042371bcf84f1935903ec57d204e3b7abd84..201599988e20219b6a99bf1594ad6c0c19e09038 100644 +index d907e24d563e27acab2f2bf9711b1755ea9afd19..75170c8d3be477a6ea2a1d62018a6ab630b0e54e 100644 --- a/net/minecraft/world/SimpleContainer.java +++ b/net/minecraft/world/SimpleContainer.java @@ -211,7 +211,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { @@ -111,7 +111,7 @@ index 133e042371bcf84f1935903ec57d204e3b7abd84..201599988e20219b6a99bf1594ad6c0c public void setItem(int index, ItemStack stack) { this.items.set(index, stack); - stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util this.setChanged(); } @@ -120,125 +120,88 @@ index 133e042371bcf84f1935903ec57d204e3b7abd84..201599988e20219b6a99bf1594ad6c0c private void moveItemsBetweenStacks(ItemStack stack, ItemStack other) { - int maxStackSize = this.getMaxStackSize(other); -+ int maxStackSize = this.getMaxStackLeaves(other); // Leaves - stackable shulker boxes ++ int maxStackSize = this.getMaxStackLeaves(other); // Leaves - item over-stack util int min = Math.min(stack.getCount(), maxStackSize - other.getCount()); if (min > 0) { other.grow(min); diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index 6c0ebfb2be4e8b884456a2aa3d5fdc87e45a0e3c..b0e60d1d2a44bb35c87c35e82a172a38406b6c54 100644 +index 51804b611f469f2ab53e455e8c633b867b00cc88..df24938d5136948b151d3c1c72ccb2ec97640478 100644 --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -281,10 +281,52 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -279,10 +279,15 @@ public class ItemEntity extends Entity implements TraceableEntity { private boolean isMergable() { ItemStack item = this.getItem(); - return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < item.getMaxStackSize(); // Paper - Alternative item-despawn-rate -+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(item); // Paper - Alternative item-despawn-rate // Leaves - stackable shulker boxes ++ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && item.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item); // Paper - Alternative item-despawn-rate // Leaves - item over-stack util } -+ // Leaves end - stackable shulker boxes -+ private boolean tryStackShulkerBoxes(ItemEntity other) { -+ ItemStack selfStack = this.getItem(); -+ if (org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize == 1 || -+ !(selfStack.getItem() instanceof net.minecraft.world.item.BlockItem blockItem) || -+ !(blockItem.getBlock() instanceof net.minecraft.world.level.block.ShulkerBoxBlock) -+ ) { -+ return false; -+ } -+ -+ ItemStack otherStack = other.getItem(); -+ if (selfStack.getItem() == otherStack.getItem() -+ && org.leavesmc.leaves.util.ShulkerBoxUtils.shulkerBoxNoItem(selfStack) -+ && org.leavesmc.leaves.util.ShulkerBoxUtils.shulkerBoxNoItem(otherStack) -+ && Objects.equals(selfStack.getComponents(), otherStack.getComponents()) // empty block entity tags are cleaned up when spawning -+ && selfStack.getCount() != org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize) { -+ int amount = Math.min(otherStack.getCount(), org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize - selfStack.getCount()); -+ -+ selfStack.grow(amount); -+ this.setItem(selfStack); -+ -+ this.pickupDelay = Math.max(other.pickupDelay, this.pickupDelay); -+ this.age = Math.min(other.getAge(), this.age); -+ -+ otherStack.shrink(amount); -+ if (otherStack.isEmpty()) { -+ other.discard(); -+ } -+ else { -+ other.setItem(otherStack); -+ } -+ return true; -+ } -+ return false; -+ } -+ // Leaves end - stackable shulker boxes -+ private void tryToMerge(ItemEntity itemEntity) { -+ // Leaves start - stackable shulker boxes -+ if (tryStackShulkerBoxes(itemEntity)) { ++ // Leaves start - item over-stack util ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.tryStackItems(this, itemEntity)) { + return; + } -+ // Leaves end - stackable shulker boxes ++ // Leaves end - item over-stack util ItemStack item = this.getItem(); ItemStack item1 = itemEntity.getItem(); if (Objects.equals(this.target, itemEntity.target) && areMergable(item, item1)) { diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java -index d9cb4f0ed0c4f63362c837aeef3c4194911455c9..57bf2819271b3293a065b58d31b609f8463811b4 100644 +index a6bb436dc80daf6901dc027a6011ead4b3ed27e2..71df58ae26325a2d28b6679733c474c0c59f7654 100644 --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -148,10 +148,12 @@ public class Inventory implements Container, Nameable { +@@ -165,10 +165,12 @@ public class Inventory implements Container, Nameable { } private boolean hasRemainingSpaceForItem(ItemStack destination, ItemStack origin) { -+ // Leaves start - stackable shulker boxes ++ // Leaves start - item over-stack util return !destination.isEmpty() - && destination.isStackable() - && destination.getCount() < this.getMaxStackSize(destination) -+ && org.leavesmc.leaves.util.ShulkerBoxUtils.isStackable(destination) -+ && destination.getCount() < org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(destination) ++ && org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(destination) ++ && destination.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(destination) && ItemStack.isSameItemSameComponents(destination, origin); // Paper - check if itemstack is stackable first -+ // Leaves end - stackable shulker boxes ++ // Leaves end - item over-stack util } // CraftBukkit start - Watch method above! :D -@@ -164,7 +166,7 @@ public class Inventory implements Container, Nameable { +@@ -181,7 +183,7 @@ public class Inventory implements Container, Nameable { } if (this.hasRemainingSpaceForItem(itemInSlot, itemStack)) { - remains -= (itemInSlot.getMaxStackSize() < this.getMaxStackSize() ? itemInSlot.getMaxStackSize() : this.getMaxStackSize()) - itemInSlot.getCount(); -+ remains -= (org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemInSlot) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemInSlot) : this.getMaxStackSize()) - itemInSlot.getCount(); // Leaves - stackable shulker boxes ++ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInSlot) : this.getMaxStackSize()) - itemInSlot.getCount(); // Leaves - item over-stack util } if (remains <= 0) { return itemStack.getCount(); -@@ -173,7 +175,7 @@ public class Inventory implements Container, Nameable { +@@ -190,7 +192,7 @@ public class Inventory implements Container, Nameable { ItemStack itemInOffhand = this.equipment.get(EquipmentSlot.OFFHAND); if (this.hasRemainingSpaceForItem(itemInOffhand, itemStack)) { - remains -= (itemInOffhand.getMaxStackSize() < this.getMaxStackSize() ? itemInOffhand.getMaxStackSize() : this.getMaxStackSize()) - itemInOffhand.getCount(); -+ remains -= (org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemInOffhand) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemInOffhand) : this.getMaxStackSize()) - itemInOffhand.getCount(); // Leaves - stackable shulker boxes ++ remains -= (org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) < this.getMaxStackSize() ? org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemInOffhand) : this.getMaxStackSize()) - itemInOffhand.getCount(); // Leaves - item over-stack util } if (remains <= 0) { return itemStack.getCount(); -@@ -297,7 +299,7 @@ public class Inventory implements Container, Nameable { +@@ -314,7 +316,7 @@ public class Inventory implements Container, Nameable { this.setItem(slot, item); } - int i = this.getMaxStackSize(item) - item.getCount(); -+ int i = this.getMaxStackLeaves(item) - item.getCount(); // Leaves - stackable shulker boxes ++ int i = this.getMaxStackLeaves(item) - item.getCount(); // Leaves - item over-stack util int min = Math.min(count, i); if (min == 0) { return count; -@@ -403,7 +405,7 @@ public class Inventory implements Container, Nameable { +@@ -420,7 +422,7 @@ public class Inventory implements Container, Nameable { break; } - int i = stack.getMaxStackSize() - this.getItem(slotWithRemainingSpace).getCount(); -+ int i = org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack) - this.getItem(slotWithRemainingSpace).getCount(); // Leaves - stackable shulker boxes ++ int i = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack) - this.getItem(slotWithRemainingSpace).getCount(); // Leaves - item over-stack util if (this.add(slotWithRemainingSpace, stack.split(i)) && sendPacket && this.player instanceof ServerPlayer serverPlayer) { serverPlayer.connection.send(this.createInventoryUpdatePacket(slotWithRemainingSpace)); } diff --git a/net/minecraft/world/entity/player/StackedItemContents.java b/net/minecraft/world/entity/player/StackedItemContents.java -index 83ccde54c625d40dc595e000c533f60aa929bd5a..1b92676459468d42931b84e5ceb19e8d30302f06 100644 +index 83ccde54c625d40dc595e000c533f60aa929bd5a..6779503888e6d311758cffde582b0efbd66a33de 100644 --- a/net/minecraft/world/entity/player/StackedItemContents.java +++ b/net/minecraft/world/entity/player/StackedItemContents.java @@ -23,7 +23,7 @@ public class StackedItemContents { @@ -246,12 +209,12 @@ index 83ccde54c625d40dc595e000c533f60aa929bd5a..1b92676459468d42931b84e5ceb19e8d public void accountStack(ItemStack stack) { - this.accountStack(stack, stack.getMaxStackSize()); -+ this.accountStack(stack, org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack)); // Leaves - stackable shulker boxes ++ this.accountStack(stack, org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); // Leaves - item over-stack util } public void accountStack(ItemStack stack, int maxStackSize) { diff --git a/net/minecraft/world/entity/vehicle/ContainerEntity.java b/net/minecraft/world/entity/vehicle/ContainerEntity.java -index feebd1610ebd3c26a337259c14f5c774dc72b937..7df6ff842e41763aec2d88d1f8a5f7503932d905 100644 +index 02d2efef2dc0f0e12eac0c71fa290af706f7694d..99f109e2653eff10c011f380694bd77a76381cee 100644 --- a/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -163,7 +163,7 @@ public interface ContainerEntity extends Container, MenuProvider { @@ -259,61 +222,61 @@ index feebd1610ebd3c26a337259c14f5c774dc72b937..7df6ff842e41763aec2d88d1f8a5f750 this.unpackChestVehicleLootTable(null); this.getItemStacks().set(slot, stack); - stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util } default SlotAccess getChestVehicleSlot(final int index) { diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index 2a4763c951ddc78c9d8a39e661e59bbffc5cf109..8aa689129334f75986fb7a18895e2c3fb3c365c8 100644 +index e5811924577fb04fd2d67fb4a32a9de1dbe3c7b1..863b9ab56304a58e8ecbe43657857b95a19cea87 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -271,6 +271,13 @@ public abstract class AbstractContainerMenu { +@@ -295,6 +295,13 @@ public abstract class AbstractContainerMenu { this.sendAllDataToRemote(); } -+ // Leaves start - stackable shulker boxes ++ // Leaves start - item over-stack util + public void sendSingleSlot(int slotIndex, ItemStack item) { + if (this.synchronizer != null) { + this.synchronizer.sendSlotChange(this, slotIndex, item); + } + } -+ // Leaves end - stackable shulker boxes ++ // Leaves end - item over-stack util private void updateDataSlotListeners(int slotIndex, int value) { for (ContainerListener containerListener : this.containerListeners) { containerListener.dataChanged(this, slotIndex, value); -@@ -428,7 +435,7 @@ public abstract class AbstractContainerMenu { +@@ -452,7 +459,7 @@ public abstract class AbstractContainerMenu { && (this.quickcraftType == 2 || carried1.getCount() >= this.quickcraftSlots.size()) && this.canDragTo(slot1)) { int i2 = slot1.hasItem() ? slot1.getItem().getCount() : 0; - int min = Math.min(itemStack.getMaxStackSize(), slot1.getMaxStackSize(itemStack)); -+ int min = Math.min(org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack), slot1.getMaxStackSize(itemStack)); // Leaves - stackable shulker boxes ++ int min = Math.min(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack), slot1.getMaxStackSize(itemStack)); // Leaves - item over-stack util int min1 = Math.min(getQuickCraftPlaceCount(this.quickcraftSlots, this.quickcraftType, itemStack) + i2, min); count -= min1 - i2; // slot1.setByPlayer(itemStack.copyWithCount(min1)); -@@ -542,7 +549,7 @@ public abstract class AbstractContainerMenu { +@@ -564,7 +571,7 @@ public abstract class AbstractContainerMenu { slot.setByPlayer(carried2); } } else if (ItemStack.isSameItemSameComponents(carried, carried2)) { - Optional optional1 = slot.tryRemove(carried.getCount(), carried2.getMaxStackSize() - carried2.getCount(), player); -+ Optional optional1 = slot.tryRemove(carried.getCount(), org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(carried2) - carried2.getCount(), player); // Leaves - stackable shulker boxes ++ Optional optional1 = slot.tryRemove(carried.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(carried2) - carried2.getCount(), player); // Leaves - item over-stack util optional1.ifPresent(itemStack2 -> { carried2.grow(itemStack2.getCount()); slot.onTake(player, itemStack2); -@@ -604,7 +611,7 @@ public abstract class AbstractContainerMenu { +@@ -626,7 +633,7 @@ public abstract class AbstractContainerMenu { Slot slot2 = this.slots.get(slotId); if (slot2.hasItem()) { ItemStack itemStack = slot2.getItem(); - this.setCarried(itemStack.copyWithCount(itemStack.getMaxStackSize())); -+ this.setCarried(itemStack.copyWithCount(org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack))); // Leaves - stackable shulker boxes ++ this.setCarried(itemStack.copyWithCount(org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack))); // Leaves - item over-stack util } } else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotId >= 0) { Slot slot2 = this.slots.get(slotId); -@@ -635,15 +642,15 @@ public abstract class AbstractContainerMenu { +@@ -657,15 +664,15 @@ public abstract class AbstractContainerMenu { int maxStackSize = button == 0 ? 1 : -1; for (int i3 = 0; i3 < 2; i3++) { - for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < itemStack.getMaxStackSize(); i4 += maxStackSize) { -+ for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack); i4 += maxStackSize) { // Leaves - stackable shulker boxes ++ for (int i4 = count; i4 >= 0 && i4 < this.slots.size() && itemStack.getCount() < org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); i4 += maxStackSize) { // Leaves - item over-stack util Slot slot3 = this.slots.get(i4); if (slot3.hasItem() && canItemQuickReplace(slot3, itemStack, true) @@ -322,49 +285,49 @@ index 2a4763c951ddc78c9d8a39e661e59bbffc5cf109..8aa689129334f75986fb7a18895e2c3f ItemStack item1 = slot3.getItem(); - if (i3 != 0 || item1.getCount() != item1.getMaxStackSize()) { - ItemStack itemStack1 = slot3.safeTake(item1.getCount(), itemStack.getMaxStackSize() - itemStack.getCount(), player); -+ if (i3 != 0 || item1.getCount() != org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(item1)) { // Leaves - stackable shulker boxes -+ ItemStack itemStack1 = slot3.safeTake(item1.getCount(), org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack) - itemStack.getCount(), player); // Leaves - stackable shulker boxes ++ if (i3 != 0 || item1.getCount() != org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(item1)) { // Leaves - item over-stack util ++ ItemStack itemStack1 = slot3.safeTake(item1.getCount(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack) - itemStack.getCount(), player); // Leaves - item over-stack util itemStack.grow(itemStack1.getCount()); } } -@@ -761,7 +768,7 @@ public abstract class AbstractContainerMenu { +@@ -783,7 +790,7 @@ public abstract class AbstractContainerMenu { i = endIndex - 1; } - if (stack.isStackable()) { -+ if (org.leavesmc.leaves.util.ShulkerBoxUtils.isStackable(stack)) { // Leaves - stackable shulker boxes ++ if (org.leavesmc.leaves.util.ItemOverstackUtils.isStackable(stack)) { // Leaves - item over-stack util while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) { Slot slot = this.slots.get(i); ItemStack item = slot.getItem(); -@@ -862,7 +869,7 @@ public abstract class AbstractContainerMenu { +@@ -884,7 +891,7 @@ public abstract class AbstractContainerMenu { public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) { boolean flag = slot == null || !slot.hasItem(); return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem()) - ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= stack.getMaxStackSize() -+ ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack) // Leaves - stackable shulker boxes ++ ? slot.getItem().getCount() + (stackSizeMatters ? 0 : stack.getCount()) <= org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack) // Leaves - item over-stack util : flag; } -@@ -870,7 +877,7 @@ public abstract class AbstractContainerMenu { +@@ -892,7 +899,7 @@ public abstract class AbstractContainerMenu { return switch (type) { case 0 -> Mth.floor((float)stack.getCount() / slots.size()); case 1 -> 1; - case 2 -> stack.getMaxStackSize(); -+ case 2 -> org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack); // Leaves - stackable shulker boxes ++ case 2 -> org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack); // Leaves - item over-stack util default -> stack.getCount(); }; } -@@ -892,7 +899,7 @@ public abstract class AbstractContainerMenu { +@@ -914,7 +921,7 @@ public abstract class AbstractContainerMenu { for (int i = 0; i < container.getContainerSize(); i++) { ItemStack item = container.getItem(i); if (!item.isEmpty()) { - f += (float)item.getCount() / container.getMaxStackSize(item); -+ f += (float)item.getCount() / container.getMaxStackLeaves(item); // Leaves - stackable shulker boxes ++ f += Math.clamp((float) item.getCount() / container.getMaxStackSize(item), 0f, 1f); // Leaves - item over-stack util } } diff --git a/net/minecraft/world/inventory/MerchantContainer.java b/net/minecraft/world/inventory/MerchantContainer.java -index 1e5dfb1f9e371fa23cdfa9280797aa0e183d4cd2..cf87267130c0aebd38206556261929d6f6383bc9 100644 +index 1e5dfb1f9e371fa23cdfa9280797aa0e183d4cd2..1a593d5bfc4574fd071604105422cd1d395648b8 100644 --- a/net/minecraft/world/inventory/MerchantContainer.java +++ b/net/minecraft/world/inventory/MerchantContainer.java @@ -109,7 +109,7 @@ public class MerchantContainer implements Container { @@ -372,12 +335,12 @@ index 1e5dfb1f9e371fa23cdfa9280797aa0e183d4cd2..cf87267130c0aebd38206556261929d6 public void setItem(int index, ItemStack stack) { this.itemStacks.set(index, stack); - stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util if (this.isPaymentSlot(index)) { this.updateSellItem(); } diff --git a/net/minecraft/world/inventory/Slot.java b/net/minecraft/world/inventory/Slot.java -index 5ceb8964476b40db4511bec91ff13c4f522a1357..371bad86218971d6e031c6d74307b2ab0d460997 100644 +index 5ceb8964476b40db4511bec91ff13c4f522a1357..f416d7976e41a06b5a8be93485eaa233ffceda5c 100644 --- a/net/minecraft/world/inventory/Slot.java +++ b/net/minecraft/world/inventory/Slot.java @@ -75,7 +75,7 @@ public class Slot { @@ -385,41 +348,41 @@ index 5ceb8964476b40db4511bec91ff13c4f522a1357..371bad86218971d6e031c6d74307b2ab public int getMaxStackSize(ItemStack stack) { - return Math.min(this.getMaxStackSize(), stack.getMaxStackSize()); -+ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack)); // Leaves - stackable shulker boxes ++ return Math.min(this.getMaxStackSize(), org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(stack)); // Leaves - item over-stack util } @Nullable diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index 24ecca78dc1140b6fc47d59f2acefca6bc2b0220..649d17dcd7856e3b1344192d8ea4b2e9f73fc03b 100644 +index da16f4831c875e07c25d7ed041bed493db614658..3ba64f91883b88f3131d4582c771b511bbccfcd9 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -165,7 +165,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -162,7 +162,7 @@ public final class ItemStack implements DataComponentHolder { @Deprecated @Nullable private Item item; - PatchedDataComponentMap components; -+ public PatchedDataComponentMap components; // Leaves - stackable shulker boxes ++ public PatchedDataComponentMap components; // Leaves - item over-stack util @Nullable private Entity entityRepresentation; -@@ -192,7 +192,8 @@ public final class ItemStack implements DataComponentHolder { +@@ -189,7 +189,8 @@ public final class ItemStack implements DataComponentHolder { } else { Holder holder = Item.STREAM_CODEC.decode(buffer); DataComponentPatch dataComponentPatch = codec.decode(buffer); - return new ItemStack(holder, varInt, dataComponentPatch); + ItemStack itemStack = new ItemStack(holder, varInt, dataComponentPatch); -+ return org.leavesmc.leaves.util.ShulkerBoxUtils.decodeMaxStackSize(itemStack); ++ return org.leavesmc.leaves.util.ItemOverstackUtils.decodeMaxStackSize(itemStack); } } -@@ -201,13 +202,15 @@ public final class ItemStack implements DataComponentHolder { +@@ -198,13 +199,15 @@ public final class ItemStack implements DataComponentHolder { if (value.isEmpty() || value.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() buffer.writeVarInt(0); } else { - buffer.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), value, value.getCount())); // Paper - potentially sanitize count - Item.STREAM_CODEC.encode(buffer, value.getItemHolder()); -+ // Leaves start - stackable shulker boxes -+ final ItemStack itemStack = org.leavesmc.leaves.util.ShulkerBoxUtils.encodeMaxStackSize(value.copy()); ++ // Leaves start - item over-stack util ++ final ItemStack itemStack = org.leavesmc.leaves.util.ItemOverstackUtils.encodeMaxStackSize(value.copy()); + buffer.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), itemStack, itemStack.getCount())); // Paper - potentially sanitize count + Item.STREAM_CODEC.encode(buffer, itemStack.getItemHolder()); // Paper start - adventure; conditionally render translatable components @@ -432,50 +395,17 @@ index 24ecca78dc1140b6fc47d59f2acefca6bc2b0220..649d17dcd7856e3b1344192d8ea4b2e9 } finally { net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev); } -@@ -302,7 +305,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -299,7 +302,7 @@ public final class ItemStack implements DataComponentHolder { for (ItemStack itemStack : itemContainerContents.nonEmptyItems()) { int count = itemStack.getCount(); - int maxStackSize = itemStack.getMaxStackSize(); -+ int maxStackSize = org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(itemStack); // Leaves - stackable shulker boxes ++ int maxStackSize = org.leavesmc.leaves.util.ItemOverstackUtils.getItemStackMaxCount(itemStack); // Leaves - item over-stack util if (count > maxStackSize) { return DataResult.error(() -> "Item stack with count of " + count + " was larger than maximum: " + maxStackSize); } -diff --git a/net/minecraft/world/level/block/AbstractCauldronBlock.java b/net/minecraft/world/level/block/AbstractCauldronBlock.java -index ad3f32888afd8b5f0038445a1b0fcc8cacec9fe2..18b7b7fe68c54a400f269f5ff1d09fe9e3d519b8 100644 ---- a/net/minecraft/world/level/block/AbstractCauldronBlock.java -+++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java -@@ -62,9 +62,27 @@ public abstract class AbstractCauldronBlock extends Block { - ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult - ) { - CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem()); -- return cauldronInteraction.interact(state, level, pos, player, hand, stack, hitResult.getDirection()); // Paper - pass hit direction -+ return wrapInteractor(cauldronInteraction, state, level, pos, player, hand, stack, hitResult.getDirection()); // Paper - pass hit direction // Leaves - stackable shulker boxes - } - -+ // Leaves start - stackable shulker boxes -+ private InteractionResult wrapInteractor(CauldronInteraction cauldronBehavior, BlockState blockState, Level world, BlockPos blockPos, Player playerEntity, InteractionHand hand, ItemStack itemStack, net.minecraft.core.Direction hitDirection) { -+ int count = -1; -+ if (org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize > 1 && itemStack.getItem() instanceof net.minecraft.world.item.BlockItem bi && -+ bi.getBlock() instanceof ShulkerBoxBlock) { -+ count = itemStack.getCount(); -+ } -+ InteractionResult result = cauldronBehavior.interact(blockState, world, blockPos, playerEntity, hand, itemStack, hitDirection); -+ if (count > 0 && result.consumesAction()) { -+ ItemStack current = playerEntity.getItemInHand(hand); -+ if (current.getItem() instanceof net.minecraft.world.item.BlockItem bi && bi.getBlock() instanceof ShulkerBoxBlock) { -+ current.setCount(count); -+ } -+ } -+ return result; -+ } -+ // Leaves end - stackable shulker boxes -+ - @Override - protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { - return SHAPE; diff --git a/net/minecraft/world/level/block/CrafterBlock.java b/net/minecraft/world/level/block/CrafterBlock.java -index 38b03c7b02bdfc579e5e126c12de3d878e26d188..33e24f2c3b63b2d3b55dfae2f2e55869abeed055 100644 +index 38b03c7b02bdfc579e5e126c12de3d878e26d188..caf31218a1aff84367da126ee1dc46b8c8a1e5d1 100644 --- a/net/minecraft/world/level/block/CrafterBlock.java +++ b/net/minecraft/world/level/block/CrafterBlock.java @@ -192,7 +192,7 @@ public class CrafterBlock extends BaseEntityBlock { @@ -483,12 +413,12 @@ index 38b03c7b02bdfc579e5e126c12de3d878e26d188..33e24f2c3b63b2d3b55dfae2f2e55869 Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction)); ItemStack itemStack = stack.copy(); - if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackSize(stack))) { -+ if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackLeaves(stack))) { // Leaves - stackable shulker boxes ++ if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackLeaves(stack))) { // Leaves - item over-stack util // CraftBukkit start - InventoryMoveItemEvent org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack); diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java -index 7729c33cad94cf2b4162324be75713650fc9d378..78b3bdb668320e9cf2fb09b59929fac43cf56aca 100644 +index bebe8737b71fc37336342f14b6ea4cfab12d3f34..4fdb3c36b39213f01f86ba281c7b62af99f5dcce 100644 --- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java @@ -409,7 +409,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit @@ -496,25 +426,25 @@ index 7729c33cad94cf2b4162324be75713650fc9d378..78b3bdb668320e9cf2fb09b59929fac4 boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, stack); this.items.set(index, stack); - stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util if (index == 0 && !flag && this.level instanceof ServerLevel serverLevel) { this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API this.cookingTimer = 0; diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -index c63370fd458fb4f7190b79b1a8174fcc92d88f9c..4cca3fbbb93bb76d5d501dfad6997d909211809e 100644 +index 5a094257a31f0500278a706a418e1697f8810ffb..63d6a43dab067aa4c8fb67095c455130196eef9f 100644 --- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -@@ -148,7 +148,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co +@@ -145,7 +145,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co @Override public void setItem(int slot, ItemStack stack) { this.getItems().set(slot, stack); - stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util this.setChanged(); } diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 2d979850378c05ce569782d8e04a452f986612a7..a2fe5fdf50ae731e423821a0d1c52141b478e0be 100644 +index e53b40c70c0a61cbe14a236a99725daa28512b0b..d152ad88e8e873a0164b2394516bd10f23c7b263 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -113,7 +113,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -522,7 +452,7 @@ index 2d979850378c05ce569782d8e04a452f986612a7..a2fe5fdf50ae731e423821a0d1c52141 this.unpackLootTable(null); this.getItems().set(index, stack); - stack.limitSize(this.getMaxStackSize(stack)); -+ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util } @Override @@ -531,10 +461,10 @@ index 2d979850378c05ce569782d8e04a452f986612a7..a2fe5fdf50ae731e423821a0d1c52141 // Spigot start - SPIGOT-6693, SimpleContainer#setItem ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size - if (!stack.isEmpty() && stack.getCount() > destination.getMaxStackSize()) { -+ if (!stack.isEmpty() && (stack.getCount() > destination.getMaxStackSize() || stack.getCount() > stack.getMaxStackSize())) { // Leaves - stackable shulker boxes ++ if (!stack.isEmpty() && (stack.getCount() > destination.getMaxStackSize() || stack.getCount() > stack.getMaxStackSize())) { // Leaves - item over-stack util leftover = stack; // Paper - Make hoppers respect inventory max stack size - stack = stack.split(destination.getMaxStackSize()); -+ stack = stack.split(Math.min(destination.getMaxStackSize(), stack.getMaxStackSize())); // Leaves - stackable shulker boxes ++ stack = stack.split(Math.min(destination.getMaxStackSize(), stack.getMaxStackSize())); // Leaves - item over-stack util } // Spigot end ignoreBlockEntityUpdates = true; // Paper - Perf: Optimize Hoppers diff --git a/leaves-server/minecraft-patches/features/0035-Return-nether-portal-fix.patch b/leaves-server/minecraft-patches/features/0035-Return-nether-portal-fix.patch index 04d9546b..3ced42e6 100644 --- a/leaves-server/minecraft-patches/features/0035-Return-nether-portal-fix.patch +++ b/leaves-server/minecraft-patches/features/0035-Return-nether-portal-fix.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Return nether portal fix This patch is powered by NetherPortalFix(https://github.com/TwelveIterationMods/NetherPortalFix) diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 66110486725de7967e55839043b9fc9690e4c0f5..f144a8bd5eb55ce093ad92ffd1304860dc52c1b1 100644 +index c6adc1009df62699264d996a6eba85d7db4d3bcf..a3fe89776a6a5067dbd53a82defa0ffc92fbac1d 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1428,6 +1428,21 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1464,6 +1464,21 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), serverLevel.getWorld()); this.level().getCraftServer().getPluginManager().callEvent(changeEvent); // CraftBukkit end @@ -32,10 +32,10 @@ index 66110486725de7967e55839043b9fc9690e4c0f5..f144a8bd5eb55ce093ad92ffd1304860 if (this.isBlocking()) { this.stopUsingItem(); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 491d7b5a0cc099a3eb658e19cbe9d97b4419382c..72c2762485da81d3a252290455f57a8cf81dfe66 100644 +index 742a49c9f1cec6a7ed343b1f0072fc36bb3df26b..1fe310309311d00d6889b706bb1a468323204dd9 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -863,6 +863,20 @@ public abstract class PlayerList { +@@ -822,6 +822,20 @@ public abstract class PlayerList { if (fromWorld != level) { org.bukkit.event.player.PlayerChangedWorldEvent event = new org.bukkit.event.player.PlayerChangedWorldEvent(player.getBukkitEntity(), fromWorld.getWorld()); this.server.server.getPluginManager().callEvent(event); @@ -57,10 +57,10 @@ index 491d7b5a0cc099a3eb658e19cbe9d97b4419382c..72c2762485da81d3a252290455f57a8c // Save player file again if they were disconnected diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 108430b3934a6f9757e7be50d77e760bbade669c..6893ca36cd4ae9a62fecedb1167cc6cf797a7f8f 100644 +index 942be06bebe8c3fca0b0c33fa387e30deda8dd7c..bc19f0bf079d6a7fa2fc8aaed6477da5e57d32da 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -245,7 +245,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -257,7 +257,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin protected ItemStack useItem = ItemStack.EMPTY; public int useItemRemaining; protected int fallFlyTicks; @@ -70,10 +70,10 @@ index 108430b3934a6f9757e7be50d77e760bbade669c..6893ca36cd4ae9a62fecedb1167cc6cf @Nullable private DamageSource lastDamageSource; diff --git a/net/minecraft/world/level/block/NetherPortalBlock.java b/net/minecraft/world/level/block/NetherPortalBlock.java -index 2f08780430fc643991ffb4aeba1f1ae8e78944d2..171b383efabbbe849aff28832c47076f85a46307 100644 +index 6c5629a6f5f91496a55eb0bf281ceae1567915b1..3aabae6e27e692aa65cc931e57306426e0f4d645 100644 --- a/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -184,7 +184,18 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -179,7 +179,18 @@ public class NetherPortalBlock extends Block implements Portal { @Nullable private TeleportTransition getExitPortal(ServerLevel level, Entity entity, BlockPos pos, BlockPos exitPos, boolean isNether, WorldBorder worldBorder, int searchRadius, boolean canCreatePortal, int createRadius) { // CraftBukkit diff --git a/leaves-server/minecraft-patches/features/0036-Leaves-Extra-Yggdrasil-Service.patch b/leaves-server/minecraft-patches/features/0036-Leaves-Extra-Yggdrasil-Service.patch index 576f4353..7fa34772 100644 --- a/leaves-server/minecraft-patches/features/0036-Leaves-Extra-Yggdrasil-Service.patch +++ b/leaves-server/minecraft-patches/features/0036-Leaves-Extra-Yggdrasil-Service.patch @@ -18,10 +18,10 @@ index 8c3151c25c172b846f0d028b5100718ada2d09d7..d59d05f8894481fb5ebe1aeb8ee7a162 private final String baseUrl; private final URL joinUrl; diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 9c9b601a3f903bebb0dd1bda0e24745587229727..4cde785a679dccc3dfa42272e6094328e9ce98c1 100644 +index fd3553bdc1c3cdbf6aa3dc00e0a4987f8eaa4fb8..e673df664b06c654a7be0622874b9b27ad7ef20f 100644 --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -177,7 +177,7 @@ public class Main { +@@ -178,7 +178,7 @@ public class Main { file = new File(bukkitConfiguration.getString("settings.world-container", ".")); } // Paper end - fix SPIGOT-5824 @@ -31,10 +31,10 @@ index 9c9b601a3f903bebb0dd1bda0e24745587229727..4cde785a679dccc3dfa42272e6094328 String string = Optional.ofNullable((String) optionSet.valueOf("world")).orElse(dedicatedServerSettings.getProperties().levelName); LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(file.toPath()); diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 105c207b8db2c505f256f4104642af5929b50aa9..50f73905e6785d87a0faf886802d956a1c7b9751 100644 +index 11728fa48bb144bbe933eb8fa2df22b52ac1b5a5..7e339cb26a132487ac0ab91d3db7e4885bacd545 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -244,7 +244,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Thu, 16 Feb 2023 17:25:01 +0800 -Subject: [PATCH] Configurable vanilla random +Subject: [PATCH] NOT_FINISH Configurable vanilla random diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 632a1cb5eee13d7287915433e9e646ec4a3a1a09..0e5c4aa2b8856c7b88ff90031715a55c4a1bf89e 100644 +index 089b50dbae2ae351d81deb041663f8885e3bfae1..b922ac57ca5bbe9e126be9b24a79718bf62888f6 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -261,7 +261,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -281,7 +281,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public double yOld; public double zOld; public boolean noPhysics; - public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random + public final RandomSource random = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? RandomSource.create() : SHARED_RANDOM; // Paper - Share random for entities to make them more random // Leaves - but mojang use it, optimize? no! public int tickCount; - private int remainingFireTicks = -this.getFireImmuneTicks(); + private int remainingFireTicks; public boolean wasTouchingWater; diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java -index edca2fa21e600fa1e7ef91af673adaae7d4c86c4..9007128a4619ab6130424786ae81c23ae38e55e9 100644 +index d40954f03c865bfbc5beb308bbcf7b7c9ac48eb9..bee8374eaca826de1a167c4c98a1a09aad8287d0 100644 --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java -@@ -801,7 +801,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -802,7 +802,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @VisibleForDebug public class BeeGoToHiveGoal extends Bee.BaseBeeGoal { public static final int MAX_TRAVELLING_TICKS = 2400; -- int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues -+ int travellingTicks = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? Bee.this.level().random.nextInt(10) : Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues // Leaves - why no vanilla +- int travellingTicks; ++ int travellingTicks; // TODO: int travellingTicks = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? Bee.this.level().random.nextInt(10) : Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues // Leaves - why no vanilla private static final int MAX_BLACKLISTED_TARGETS = 3; final List blacklistedTargets = Lists.newArrayList(); @Nullable -@@ -917,7 +917,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -918,7 +918,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { public class BeeGoToKnownFlowerGoal extends Bee.BaseBeeGoal { private static final int MAX_TRAVELLING_TICKS = 2400; -- int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues -+ int travellingTicks = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? Bee.this.level().random.nextInt(10) : Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues // Leaves - why no vanilla +- int travellingTicks; ++ int travellingTicks; // TODO: int travellingTicks = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? Bee.this.level().random.nextInt(10) : Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues // Leaves - why no vanilla BeeGoToKnownFlowerGoal() { this.setFlags(EnumSet.of(Goal.Flag.MOVE)); @@ -53,10 +53,10 @@ index 58e1bc90cbc32669fa6c66d214119f0c459ff38c..ea41360af5e5d49c96ca24e9c36bd52c } diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index b0e60d1d2a44bb35c87c35e82a172a38406b6c54..0cb2d5cd37171cd6e01748ed3d2ce99da1a15e3f 100644 +index 1c7bed7b7856a69f91e7f2f8970a84f0459c7929..7040d2212f20bb2cd83198b6886074a6f430ee71 100644 --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -70,7 +70,13 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -67,7 +67,13 @@ public class ItemEntity extends Entity implements TraceableEntity { // Paper start - Don't use level random in entity constructors (to make them thread-safe) this(EntityType.ITEM, level); this.setPos(posX, posY, posZ); @@ -72,10 +72,10 @@ index b0e60d1d2a44bb35c87c35e82a172a38406b6c54..0cb2d5cd37171cd6e01748ed3d2ce99d // Paper end - Don't use level random in entity constructors } diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java -index 0f28b1befd42a85ffa5462e86d5cde142f9d1196..8cbcae0ef84b160d08b677972dc70cabfb5b6c5f 100644 +index 1d7a1739d6a3a55aacb33d57a58712350b150f64..87dff2fb5246d730feca82396a68b41150e2d383 100644 --- a/net/minecraft/world/entity/item/PrimedTnt.java +++ b/net/minecraft/world/entity/item/PrimedTnt.java -@@ -69,7 +69,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { +@@ -68,7 +68,7 @@ public class PrimedTnt extends Entity implements TraceableEntity { public PrimedTnt(Level level, double x, double y, double z, @Nullable LivingEntity owner) { this(EntityType.TNT, level); this.setPos(x, y, z); diff --git a/leaves-server/minecraft-patches/features/0038-Catch-update-suppression-crash.patch b/leaves-server/minecraft-patches/features/0038-Catch-update-suppression-crash.patch index ee3b2168..9d21a97b 100644 --- a/leaves-server/minecraft-patches/features/0038-Catch-update-suppression-crash.patch +++ b/leaves-server/minecraft-patches/features/0038-Catch-update-suppression-crash.patch @@ -20,7 +20,7 @@ index 4535858701b2bb232b9d2feb2af6551526232ddc..2a51acd97afc525170e8001b76f57ad1 if (var4 instanceof ReportedException reportedException && reportedException.getCause() instanceof OutOfMemoryError) { throw makeReportedException(var4, packet, processor); diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index b40e6b156614e9248b9423d0fbf208c2dc139489..f12b397901c0a2f779221e6694cecaced7069c9e 100644 +index 46be518ca1ecc96acbd764e21c430210ceb72b1b..4a427b80ad9bc387bd774e33c844b4d67836737c 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -1725,6 +1725,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> { +@@ -245,8 +245,8 @@ public class Connection extends SimpleChannelInboundHandler> { if (this.stopReadingPackets) { return; } @@ -20,19 +20,19 @@ index 364ddf9f25ef3cb97ba788c469fee9dd495b84a7..7af8b2cf9ccfeadac1cc60541da31ba6 synchronized (PACKET_LIMIT_LOCK) { if (this.allPacketCounts != null) { diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 878d80d0cb9fddeb7916a34d39c34119d65fbe00..2ed38800fb3e3a1f4fb04c781321c642e402a854 100644 +index e0687743975db1832933661540650df86a911a80..3c7b691a60f355ebaeb96f7ba07955f5be7fd09b 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -780,7 +780,7 @@ public class ServerGamePacketListenerImpl +@@ -821,7 +821,7 @@ public class ServerGamePacketListenerImpl public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { - // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async + // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); // Paper - AsyncTabCompleteEvent; run this async // CraftBukkit start - if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits + if (!org.leavesmc.leaves.LeavesConfig.modify.disablePacketLimit && !this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits // Leaves - can disable this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect return; } -@@ -1955,6 +1955,7 @@ public class ServerGamePacketListenerImpl +@@ -2002,6 +2002,7 @@ public class ServerGamePacketListenerImpl private static int getSpamThreshold() { return io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.incomingPacketThreshold; } // Paper - Configurable threshold private boolean checkLimit(long timestamp) { @@ -40,7 +40,7 @@ index 878d80d0cb9fddeb7916a34d39c34119d65fbe00..2ed38800fb3e3a1f4fb04c781321c642 if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < getSpamThreshold() && this.limitedPackets++ >= 8) { // Paper - Configurable threshold; raise packet limit to 8 return false; } -@@ -2492,6 +2493,7 @@ public class ServerGamePacketListenerImpl +@@ -2536,6 +2537,7 @@ public class ServerGamePacketListenerImpl // Spigot start - spam exclusions private void detectRateSpam(String message) { @@ -48,7 +48,7 @@ index 878d80d0cb9fddeb7916a34d39c34119d65fbe00..2ed38800fb3e3a1f4fb04c781321c642 // CraftBukkit start - replaced with thread safe throttle if (org.spigotmc.SpigotConfig.enableSpamExclusions) { for (String exclude : org.spigotmc.SpigotConfig.spamExclusions) { -@@ -3280,7 +3282,7 @@ public class ServerGamePacketListenerImpl +@@ -3244,7 +3246,7 @@ public class ServerGamePacketListenerImpl @Override public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { // Paper start - auto recipe limit diff --git a/leaves-server/minecraft-patches/features/0044-Syncmatica-Protocol.patch b/leaves-server/minecraft-patches/features/0044-Syncmatica-Protocol.patch index f6dc636e..9365a7e3 100644 --- a/leaves-server/minecraft-patches/features/0044-Syncmatica-Protocol.patch +++ b/leaves-server/minecraft-patches/features/0044-Syncmatica-Protocol.patch @@ -6,18 +6,19 @@ Subject: [PATCH] Syncmatica Protocol This patch is Powered by Syncmatica(https://github.com/End-Tech/syncmatica) diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 2f4776fa065cb712afe9d8abc835c57777c963b7..f1372015cf5991ef80a07e7fcbd1fb9d65e9d74f 100644 +index 3c7b691a60f355ebaeb96f7ba07955f5be7fd09b..6e8e4b009a4dd52047bc8d8f8e2e27558e0d8dff 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -319,8 +319,11 @@ public class ServerGamePacketListenerImpl +@@ -323,9 +323,12 @@ public class ServerGamePacketListenerImpl this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile); this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event + this.exchangeTarget = new org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget(this); // Leaves - Syncmatica Protocol + this.playerGameConnection = new io.papermc.paper.connection.PaperPlayerGameConnection(this); // Paper } + public final org.leavesmc.leaves.protocol.syncmatica.exchange.ExchangeTarget exchangeTarget; // Leaves - Syncmatica Protocol + + // Paper start - configuration phase API @Override - public void tick() { - if (this.ackBlockChangesUpTo > -1) { + public io.papermc.paper.connection.PlayerCommonConnection getApiConnection() { diff --git a/leaves-server/minecraft-patches/features/0048-Despawn-enderman-with-block.patch b/leaves-server/minecraft-patches/features/0048-Despawn-enderman-with-block.patch index 52f07387..3d107087 100644 --- a/leaves-server/minecraft-patches/features/0048-Despawn-enderman-with-block.patch +++ b/leaves-server/minecraft-patches/features/0048-Despawn-enderman-with-block.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Despawn enderman with block diff --git a/net/minecraft/world/entity/monster/EnderMan.java b/net/minecraft/world/entity/monster/EnderMan.java -index 41c8fc535e7f0bd61e23f48ac250f362807fa062..775466831746b914947cd018d8def4b8bf1d6f15 100644 +index 6760bfd91f59139922768db5e5d362c5e7e4e473..33d4025ac997f46b7bf129c4dd3ba457c6fc9da2 100644 --- a/net/minecraft/world/entity/monster/EnderMan.java +++ b/net/minecraft/world/entity/monster/EnderMan.java -@@ -452,7 +452,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -448,7 +448,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean requiresCustomPersistence() { diff --git a/leaves-server/minecraft-patches/features/0050-Creative-fly-no-clip.patch b/leaves-server/minecraft-patches/features/0050-Creative-fly-no-clip.patch index c80e36b4..ac0770e8 100644 --- a/leaves-server/minecraft-patches/features/0050-Creative-fly-no-clip.patch +++ b/leaves-server/minecraft-patches/features/0050-Creative-fly-no-clip.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Creative fly no clip diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..f6e963d75fdcd951e5f5624f7d69cbbf6b8b480f 100644 +index 8ec6f52f58bcc985fdc758a692798a35d6c86378..0d046133ea2b6d47e089cb792cf3bc3abace70ba 100644 --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java -@@ -277,8 +277,8 @@ public abstract class Player extends LivingEntity { +@@ -287,8 +287,8 @@ public abstract class Player extends LivingEntity { @Override public void tick() { @@ -19,7 +19,7 @@ index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..f6e963d75fdcd951e5f5624f7d69cbbf this.setOnGround(false); } -@@ -471,7 +471,7 @@ public abstract class Player extends LivingEntity { +@@ -481,7 +481,7 @@ public abstract class Player extends LivingEntity { if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.SWIMMING)) { Pose desiredPose = this.getDesiredPose(); Pose pose; @@ -28,7 +28,7 @@ index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..f6e963d75fdcd951e5f5624f7d69cbbf pose = desiredPose; } else if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)) { pose = Pose.CROUCHING; -@@ -614,7 +614,7 @@ public abstract class Player extends LivingEntity { +@@ -624,7 +624,7 @@ public abstract class Player extends LivingEntity { } this.bob = this.bob + (f - this.bob) * 0.4F; @@ -37,7 +37,7 @@ index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..f6e963d75fdcd951e5f5624f7d69cbbf AABB aabb; if (this.isPassenger() && !this.getVehicle().isRemoved()) { aabb = this.getBoundingBox().minmax(this.getVehicle().getBoundingBox()).inflate(1.0, 0.0, 1.0); -@@ -1931,6 +1931,26 @@ public abstract class Player extends LivingEntity { +@@ -1949,6 +1949,26 @@ public abstract class Player extends LivingEntity { return this.gameMode() == GameType.SPECTATOR; } @@ -65,10 +65,10 @@ index 2fe76bc1c26423ed5e39453ac1b27a2cc66b1f2e..f6e963d75fdcd951e5f5624f7d69cbbf public boolean canBeHitByProjectile() { return !this.isSpectator() && super.canBeHitByProjectile(); diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java -index 0c67e5481a43bf7c02bb54a8ea1abca77d53a292..5cbd5d04de525c33715bc45826bd2ed446355505 100644 +index eff2c0418e1dc8dff1b9045d8f6ff619100964d1..8b6bbdf44a840e19722d42aec91fa1f8805f917b 100644 --- a/net/minecraft/world/item/BlockItem.java +++ b/net/minecraft/world/item/BlockItem.java -@@ -207,8 +207,9 @@ public class BlockItem extends Item { +@@ -206,8 +206,9 @@ public class BlockItem extends Item { protected boolean canPlace(BlockPlaceContext context, BlockState state) { Player player = context.getPlayer(); // CraftBukkit start @@ -93,7 +93,7 @@ index 1f0e7c391d02b18e2c89700025713ec3d759f2ea..300ee12ca9584e53e9d72e3ebfd039be org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(org.bukkit.craftbukkit.block.CraftBlock.at(context.getLevel(), clickedPos), player, org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(blockState), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent diff --git a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index 5e58113b3401268e0432235dc10b2734dbbd8b71..1f7c2d06952febd7a5d4e216b6e22794239b9325 100644 +index a820ab9a2b6dc6b95d4de61aaaad4e79c521efe4..c1d1e28daa3b4d2a0bb359af08670f5d071e51ed 100644 --- a/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java @@ -152,7 +152,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl @@ -106,10 +106,10 @@ index 5e58113b3401268e0432235dc10b2734dbbd8b71..1f7c2d06952febd7a5d4e216b6e22794 MoverType.SHULKER_BOX, new Vec3( diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index 8449545bd5278f5558567dd6b7c1522f63045f22..3d2770828d4fe1123b158e70bfe459d7cf16332a 100644 +index 0976aef81b950a062152094501372d00c20bb2b7..2841dd4896ee15d8d7ea1105d0f78b7fe41937fb 100644 --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -152,7 +152,7 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -151,7 +151,7 @@ public class PistonMovingBlockEntity extends BlockEntity { d3 = movementDirection.getStepZ(); } @@ -118,7 +118,7 @@ index 8449545bd5278f5558567dd6b7c1522f63045f22..3d2770828d4fe1123b158e70bfe459d7 // Paper - EAR items stuck in slime pushed by a piston entity.activatedTick = Math.max(entity.activatedTick, net.minecraft.server.MinecraftServer.currentTick + 10); entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, net.minecraft.server.MinecraftServer.currentTick + 10); -@@ -188,6 +188,7 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -187,6 +187,7 @@ public class PistonMovingBlockEntity extends BlockEntity { } private static void moveEntityByPiston(Direction noClipDirection, Entity entity, double progress, Direction direction) { diff --git a/leaves-server/minecraft-patches/features/0052-Elytra-aeronautics-no-chunk-load.patch b/leaves-server/minecraft-patches/features/0052-Elytra-aeronautics-no-chunk-load.patch index 06e779e8..09eb7766 100644 --- a/leaves-server/minecraft-patches/features/0052-Elytra-aeronautics-no-chunk-load.patch +++ b/leaves-server/minecraft-patches/features/0052-Elytra-aeronautics-no-chunk-load.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Elytra aeronautics no chunk load diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index 4785f9d6c53e18419a3df4a1be9c8a4f9d8cadfb..711bd09283c57e5cbe3b04d6950ecf1308fcf09c 100644 +index 019886669966c69936ae6591598c97a8afbfd3db..b6fb1f2ba8622d9d319210ea7cf0a984349444e6 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -854,7 +854,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -27,10 +27,10 @@ index 4785f9d6c53e18419a3df4a1be9c8a4f9d8cadfb..711bd09283c57e5cbe3b04d6950ecf13 SectionPos lastSectionPos = player.getLastSectionPos(); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 325e3948e5bdfddfe217c9972208582e83f2c4cb..68490d8dc26c2d5f4999361fd7ad72a83581f48f 100644 +index 31fb5ea1e33672ae71210776a0302f0ef87c6814..e6de7ef46d197c14495d4b55d094af34816fc063 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -830,6 +830,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -837,6 +837,9 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } ); @@ -41,10 +41,10 @@ index 325e3948e5bdfddfe217c9972208582e83f2c4cb..68490d8dc26c2d5f4999361fd7ad72a8 this.tickBlockEntities(); } diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 448c77f5002276eab680a96b518e8a7234806f80..655ca2ead22addbb458b89e12cb2be1d269e4f5e 100644 +index 6e8e4b009a4dd52047bc8d8f8e2e27558e0d8dff..52ef9208da25022bbc8f375696ea4f3d4e4962a3 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -541,7 +541,7 @@ public class ServerGamePacketListenerImpl +@@ -582,7 +582,7 @@ public class ServerGamePacketListenerImpl speed *= 2f; // TODO: Get the speed of the vehicle instead of the player // Paper start - Prevent moving into unloaded chunks @@ -53,19 +53,19 @@ index 448c77f5002276eab680a96b518e8a7234806f80..655ca2ead22addbb458b89e12cb2be1d !serverLevel.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position()))) || !serverLevel.areChunksLoadedForMove(rootVehicle.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(rootVehicle.position()))) )) { -@@ -1549,6 +1549,7 @@ public class ServerGamePacketListenerImpl - teleportBack = this.hasNewCollision(serverLevel, this.player, boundingBox, newBox); +@@ -1597,6 +1597,7 @@ public class ServerGamePacketListenerImpl + allowMovement = !this.hasNewCollision(serverLevel, this.player, boundingBox, newBox); } // else: no collision at all detected, why do we care? } -+ teleportBack = teleportBack && !player.elytraAeronauticsNoChunk; // Leaves - Elytra aeronautics ++ allowMovement = allowMovement || player.elytraAeronauticsNoChunk; // Leaves - Elytra aeronautics // Paper end - optimise out extra getCubes - if (teleportBack) { + if (!allowMovement) { io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK, diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index f983ea2bb9d089bd4dfd81a482fd4810c6b8ebd7..0c1a50d293638c319b34f757c0ba41d31a1538ac 100644 +index 7a82ab3b1a4a4cc7708cbec5d424b3bfcede87a9..6b3fcd3e02755ab187d075d868e9376718c218e5 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -1092,7 +1092,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1118,7 +1118,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return; } } @@ -80,7 +80,7 @@ index f983ea2bb9d089bd4dfd81a482fd4810c6b8ebd7..0c1a50d293638c319b34f757c0ba41d3 ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("move"); if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7) { -@@ -2057,6 +2063,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2131,6 +2137,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.yo = y; this.zo = d1; this.setPos(d, y, d1); @@ -89,10 +89,10 @@ index f983ea2bb9d089bd4dfd81a482fd4810c6b8ebd7..0c1a50d293638c319b34f757c0ba41d3 } diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 6893ca36cd4ae9a62fecedb1167cc6cf797a7f8f..a95fec1506af042bd3d4424e93aa3f4de9627487 100644 +index bc19f0bf079d6a7fa2fc8aaed6477da5e57d32da..1f0042d24a11c709f291a03e1699fcaf0d6571c6 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3276,6 +3276,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3328,6 +3328,11 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin this.fallFlyTicks++; } else { this.fallFlyTicks = 0; @@ -105,10 +105,10 @@ index 6893ca36cd4ae9a62fecedb1167cc6cf797a7f8f..a95fec1506af042bd3d4424e93aa3f4d if (this.isSleeping()) { diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index f6e963d75fdcd951e5f5624f7d69cbbf6b8b480f..ee8c0d0edbb296106a128c48f4186ba3a5bf9df8 100644 +index 0d046133ea2b6d47e089cb792cf3bc3abace70ba..0abdf0e520d1a0672917d60b79f467df4399e256 100644 --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java -@@ -210,6 +210,7 @@ public abstract class Player extends LivingEntity { +@@ -219,6 +219,7 @@ public abstract class Player extends LivingEntity { private int currentImpulseContextResetGraceTime = 0; public boolean affectsSpawning = true; // Paper - Affects Spawning API public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage @@ -117,11 +117,11 @@ index f6e963d75fdcd951e5f5624f7d69cbbf6b8b480f..ee8c0d0edbb296106a128c48f4186ba3 // CraftBukkit start public boolean fauxSleeping; diff --git a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -index e0e193078e550225e163149638bf9e053c0531f8..484f1c5eba3776eff86438ba02607e60c7083b3b 100644 +index d8dc196ef92e97f831cf97cd1536a46f81f9d5d1..92da11f86a95ff635277cbfcea73c48731080953 100644 --- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -@@ -328,7 +328,7 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { - this.spawningEntity = compound.read("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); // Paper +@@ -324,7 +324,7 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { + this.spawningEntity = input.read("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); // Paper } - private List getExplosions() { @@ -130,10 +130,10 @@ index e0e193078e550225e163149638bf9e053c0531f8..484f1c5eba3776eff86438ba02607e60 Fireworks fireworks = itemStack.get(DataComponents.FIREWORKS); return fireworks != null ? fireworks.explosions() : List.of(); diff --git a/net/minecraft/world/item/FireworkRocketItem.java b/net/minecraft/world/item/FireworkRocketItem.java -index 18d63d2da49451a2d5e1da7bf0c00e05e2f192bc..6c78a59b6518799c9b199c96cc4592fb48229e9a 100644 +index f86b0579e707ecfa5c2074ea22bbe383b5e11841..0e4335bb2469a4698b303b598ec773b5c7cc73ce 100644 --- a/net/minecraft/world/item/FireworkRocketItem.java +++ b/net/minecraft/world/item/FireworkRocketItem.java -@@ -57,6 +57,24 @@ public class FireworkRocketItem extends Item implements ProjectileItem { +@@ -64,6 +64,24 @@ public class FireworkRocketItem extends Item implements ProjectileItem { if (player.isFallFlying()) { ItemStack itemInHand = player.getItemInHand(hand); if (level instanceof ServerLevel serverLevel) { diff --git a/leaves-server/minecraft-patches/features/0054-Lava-riptide.patch b/leaves-server/minecraft-patches/features/0054-Lava-riptide.patch index 283a6bc9..910467eb 100644 --- a/leaves-server/minecraft-patches/features/0054-Lava-riptide.patch +++ b/leaves-server/minecraft-patches/features/0054-Lava-riptide.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Lava riptide diff --git a/net/minecraft/world/item/TridentItem.java b/net/minecraft/world/item/TridentItem.java -index df629e3f2defce5e65aaf874d7c5ddff71f39c28..a069729494d638e5f0828c12ad1186e748d0677e 100644 +index fac4c58ea5d467a8686e42676e2323fbddeb8c7b..0afe875e003704a53856fac72d2feb8b664c1207 100644 --- a/net/minecraft/world/item/TridentItem.java +++ b/net/minecraft/world/item/TridentItem.java @@ -70,7 +70,7 @@ public class TridentItem extends Item implements ProjectileItem { @@ -17,7 +17,7 @@ index df629e3f2defce5e65aaf874d7c5ddff71f39c28..a069729494d638e5f0828c12ad1186e7 return false; } else if (stack.nextDamageWillBreak()) { return false; -@@ -150,7 +150,7 @@ public class TridentItem extends Item implements ProjectileItem { +@@ -149,7 +149,7 @@ public class TridentItem extends Item implements ProjectileItem { ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.nextDamageWillBreak()) { return InteractionResult.FAIL; diff --git a/leaves-server/minecraft-patches/features/0055-No-block-update-command.patch b/leaves-server/minecraft-patches/features/0055-No-block-update-command.patch index a96f937e..601f6272 100644 --- a/leaves-server/minecraft-patches/features/0055-No-block-update-command.patch +++ b/leaves-server/minecraft-patches/features/0055-No-block-update-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] No block update command diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java -index 5e54d6de0430cd137fbe13ca8f17dc487ce52ff3..a68ca4ccec97b9fc6f9a6ae698722842cb6bf42d 100644 +index 5d4eb61af0b0f39a5d4c37f4a303fa24b3a2936d..48bb795216ca3fb301813080de403a048bbfa98c 100644 --- a/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/net/minecraft/server/level/ServerPlayerGameMode.java @@ -381,7 +381,7 @@ public class ServerPlayerGameMode { @@ -18,7 +18,7 @@ index 5e54d6de0430cd137fbe13ca8f17dc487ce52ff3..a68ca4ccec97b9fc6f9a6ae698722842 if (flag) { block.destroy(this.level, pos, blockState1); diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 7c13e7b7a547150642c4a4bddf5e8dee1d580984..ac4996dda7bcf5f20391f45e3f703b21557a1669 100644 +index ef8a072838558caab19e8a85f4b59cac570c2635..590252ca203124f0b720a73f174c92fbe49bc685 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -1089,6 +1089,11 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl diff --git a/leaves-server/minecraft-patches/features/0056-Raider-die-skip-self-raid-check.patch b/leaves-server/minecraft-patches/features/0056-Raider-die-skip-self-raid-check.patch index 5a77c777..839e84f6 100644 --- a/leaves-server/minecraft-patches/features/0056-Raider-die-skip-self-raid-check.patch +++ b/leaves-server/minecraft-patches/features/0056-Raider-die-skip-self-raid-check.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Raider die skip self raid check diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java -index e81ae747fe95c22321fc69791a6509d601826fd6..39a6a4579931d7edb7ab8c072d62cfc9b02791c8 100644 +index a495789b2d21fa9a24d5dca4ecfa196ddce49466..7b697f1dfe8131296ef55cd88a8b9d7cd884eb44 100644 --- a/net/minecraft/world/entity/raid/Raider.java +++ b/net/minecraft/world/entity/raid/Raider.java -@@ -155,7 +155,7 @@ public abstract class Raider extends PatrollingMonster { +@@ -156,7 +156,7 @@ public abstract class Raider extends PatrollingMonster { } public boolean hasRaid() { diff --git a/leaves-server/minecraft-patches/features/0057-Container-open-passthrough.patch b/leaves-server/minecraft-patches/features/0057-Container-open-passthrough.patch index 6befec05..5c5dc253 100644 --- a/leaves-server/minecraft-patches/features/0057-Container-open-passthrough.patch +++ b/leaves-server/minecraft-patches/features/0057-Container-open-passthrough.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Container open passthrough diff --git a/net/minecraft/world/entity/decoration/ItemFrame.java b/net/minecraft/world/entity/decoration/ItemFrame.java -index f9a97000b75db7999b1cbe1f72d680d4d7b803b7..91164be32436c003f2456d4510466779e1b576d8 100644 +index 90fd3ca5ecd29befa9237222e9f86a8a79a011e4..cc26f2bfd8992207fffd74b89752275abe2be623 100644 --- a/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -408,6 +408,20 @@ public class ItemFrame extends HangingEntity { +@@ -412,6 +412,20 @@ public class ItemFrame extends HangingEntity { return InteractionResult.PASS; } } else { + // Leaves start - itemFrameContainerPassthrough + if (org.leavesmc.leaves.LeavesConfig.modify.containerPassthrough && !player.isShiftKeyDown()) { -+ BlockPos pos1 = this.pos.relative(this.direction.getOpposite()); ++ BlockPos pos1 = this.pos.relative(this.getDirection().getOpposite()); + if (level().getBlockEntity(pos1) instanceof net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity) { + BlockState blockState = level().getBlockState(pos1); -+ net.minecraft.world.phys.BlockHitResult hitResult = new net.minecraft.world.phys.BlockHitResult(Vec3.atCenterOf(pos1), this.direction, pos1, false); ++ net.minecraft.world.phys.BlockHitResult hitResult = new net.minecraft.world.phys.BlockHitResult(Vec3.atCenterOf(pos1), this.getDirection(), pos1, false); + if (flag1) { + return blockState.useItemOn(itemInHand, level(), player, hand, hitResult); + } else { @@ -30,10 +30,10 @@ index f9a97000b75db7999b1cbe1f72d680d4d7b803b7..91164be32436c003f2456d4510466779 io.papermc.paper.event.player.PlayerItemFrameChangeEvent event = new io.papermc.paper.event.player.PlayerItemFrameChangeEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.ItemFrame) this.getBukkitEntity(), this.getItem().asBukkitCopy(), io.papermc.paper.event.player.PlayerItemFrameChangeEvent.ItemFrameChangeAction.ROTATE); if (!event.callEvent()) { diff --git a/net/minecraft/world/level/block/SignBlock.java b/net/minecraft/world/level/block/SignBlock.java -index a06896de4401f184e8c5cc8bad829e6412eaff22..00067809380fb3cff1dd54876c28c7a8d5b0aaee 100644 +index a2c6b0f85535b286c5649352f49e448ad587655c..3d62414778f8e18aebfa67817a86f188cb90c614 100644 --- a/net/minecraft/world/level/block/SignBlock.java +++ b/net/minecraft/world/level/block/SignBlock.java -@@ -105,6 +105,18 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -108,6 +108,18 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo } else { return InteractionResult.TRY_WITH_EMPTY_HAND; } @@ -53,9 +53,9 @@ index a06896de4401f184e8c5cc8bad829e6412eaff22..00067809380fb3cff1dd54876c28c7a8 return InteractionResult.TRY_WITH_EMPTY_HAND; } @@ -130,6 +142,25 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo - return InteractionResult.SUCCESS_SERVER; - } else if (flag) { - return InteractionResult.SUCCESS_SERVER; + return InteractionResult.SUCCESS_SERVER; + } else if (flag) { + return InteractionResult.SUCCESS_SERVER; + // Leaves start - signContainerPassthrough + } else if (org.leavesmc.leaves.LeavesConfig.modify.containerPassthrough) { + if (player.isShiftKeyDown()) { @@ -75,6 +75,6 @@ index a06896de4401f184e8c5cc8bad829e6412eaff22..00067809380fb3cff1dd54876c28c7a8 + } + return InteractionResult.PASS; + // Leaves end - signContainerPassthrough - } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity) - && player.mayBuild() - && this.hasEditableText(player, signBlockEntity, isFacingFrontText)) { + } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity) + && player.mayBuild() + && this.hasEditableText(player, signBlockEntity, isFacingFrontText)) { diff --git a/leaves-server/minecraft-patches/features/0059-Faster-chunk-serialization.patch b/leaves-server/minecraft-patches/features/0059-Faster-chunk-serialization.patch index 1f0517be..bfbe12da 100644 --- a/leaves-server/minecraft-patches/features/0059-Faster-chunk-serialization.patch +++ b/leaves-server/minecraft-patches/features/0059-Faster-chunk-serialization.patch @@ -1,33 +1,42 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Tue, 18 Jul 2023 13:14:15 +0800 +From: Martijn Muijsers +Date: Wed, 30 Nov 2022 21:51:16 +0100 Subject: [PATCH] Faster chunk serialization This patch is Powered by Gale(https://github.com/GaleMC/Gale) +License: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html) +Gale - https://galemc.org + +This patch is based on the following mixins and classes: +* "net/caffeinemc/mods/lithium/common/world/chunk/CompactingPackedIntegerArray.java" +* "net/caffeinemc/mods/lithium/common/world/chunk/LithiumHashPalette.java" +* "net/caffeinemc/mods/lithium/mixin/chunk/serialization/SimpleBitStorageMixin.java" +* "net/caffeinemc/mods/lithium/mixin/chunk/serialization/PalettedContainerMixin.java" +By: Angeline +As part of: Lithium (https://github.com/CaffeineMC/lithium-fabric) +Licensed under: LGPL-3.0 (https://www.gnu.org/licenses/lgpl-3.0.html) diff --git a/net/minecraft/util/BitStorage.java b/net/minecraft/util/BitStorage.java -index 02502d50f0255f5bbcc0ecb965abb48cc1a112da..0abee1cd9d6a5a22d3136e3711de926c3a2d4d73 100644 +index 02502d50f0255f5bbcc0ecb965abb48cc1a112da..e1f4ca261d106d176298b2afc016f5168abaa06b 100644 --- a/net/minecraft/util/BitStorage.java +++ b/net/minecraft/util/BitStorage.java -@@ -21,6 +21,8 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti - - BitStorage copy(); - -+ void compact(net.minecraft.world.level.chunk.Palette srcPalette, net.minecraft.world.level.chunk.Palette dstPalette, short[] out); // Leaves - faster chunk serialization +@@ -38,4 +38,6 @@ public interface BitStorage extends ca.spottedleaf.moonrise.patches.block_counti + return ret; + } + // Paper end - block counting + - // Paper start - block counting - // provide default impl in case mods implement this... - @Override ++ void compact(net.minecraft.world.level.chunk.Palette srcPalette, net.minecraft.world.level.chunk.Palette dstPalette, short[] out); // Gale - Lithium - faster chunk serialization + } diff --git a/net/minecraft/util/SimpleBitStorage.java b/net/minecraft/util/SimpleBitStorage.java -index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..7b4b3b8a02be3ab5ecafdea1ab74c246daf37d98 100644 +index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..8091f0c0a536047ead4966e70785962e87faad9a 100644 --- a/net/minecraft/util/SimpleBitStorage.java +++ b/net/minecraft/util/SimpleBitStorage.java -@@ -465,4 +465,44 @@ public class SimpleBitStorage implements BitStorage { +@@ -465,4 +465,45 @@ public class SimpleBitStorage implements BitStorage { super(message); } } + -+ // Leaves start - faster chunk serialization ++ // Gale start - Lithium - faster chunk serialization + @Override + public void compact(net.minecraft.world.level.chunk.Palette srcPalette, net.minecraft.world.level.chunk.Palette dstPalette, short[] out) { + if (this.size >= Short.MAX_VALUE) { @@ -65,49 +74,46 @@ index e6306a68c8652d4c5d22d5ecb1416f5f931f76ee..7b4b3b8a02be3ab5ecafdea1ab74c246 + } + } + } -+ // Leaves end - faster chunk serialization ++ // Gale end - Lithium - faster chunk serialization ++ } diff --git a/net/minecraft/util/ZeroBitStorage.java b/net/minecraft/util/ZeroBitStorage.java -index 09fd99c9cbd23b5f3c899bfb00c9b89651948ed8..50993ce7519a77c6a9d36cb925125adccda7037f 100644 +index 09fd99c9cbd23b5f3c899bfb00c9b89651948ed8..0066476f5e8289f0702ba3e525397419ef8b44ae 100644 --- a/net/minecraft/util/ZeroBitStorage.java +++ b/net/minecraft/util/ZeroBitStorage.java -@@ -63,6 +63,8 @@ public class ZeroBitStorage implements BitStorage { - return this; +@@ -80,4 +80,6 @@ public class ZeroBitStorage implements BitStorage { + return ret; } - -+ @Override public void compact(net.minecraft.world.level.chunk.Palette srcPalette, net.minecraft.world.level.chunk.Palette dstPalette, short[] out) {} // Leaves - faster chunk serialization + // Paper end - block counting + - // Paper start - block counting - @Override - public final it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap moonrise$countEntries() { ++ @Override public void compact(net.minecraft.world.level.chunk.Palette srcPalette, net.minecraft.world.level.chunk.Palette dstPalette, short[] out) {} // Gale - Lithium - faster chunk serialization + } diff --git a/net/minecraft/world/level/chunk/PaletteResize.java b/net/minecraft/world/level/chunk/PaletteResize.java -index c723606fa0be811e580ba47de8c9c575583cc930..c768443c8c6a4b05018bbc70d54b6f41e53e7738 100644 +index c723606fa0be811e580ba47de8c9c575583cc930..2483210ca43221feaa5a2f1ced5c59731d5189fc 100644 --- a/net/minecraft/world/level/chunk/PaletteResize.java +++ b/net/minecraft/world/level/chunk/PaletteResize.java @@ -1,5 +1,5 @@ package net.minecraft.world.level.chunk; -interface PaletteResize { -+public interface PaletteResize { // Leaves - package -> public ++public interface PaletteResize { int onResize(int bits, T objectAdded); } diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java -index 7da7ce0fd19896593e63edc88b492c02f926bba0..0f89bdb35fced1b9e674959ca510d2da9d4d4c5c 100644 +index a251ba67644cd02a0b00d7c8b0e2c64aa5e26291..59d48e7dc0911557c57a7e07f5f9013c010165bd 100644 --- a/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -25,6 +25,24 @@ import net.minecraft.util.ThreadingDetector; +@@ -24,6 +24,22 @@ import net.minecraft.util.ThreadingDetector; import net.minecraft.util.ZeroBitStorage; public class PalettedContainer implements PaletteResize, PalettedContainerRO { + -+ // Leaves start - faster chunk serialization ++ // Gale start - Lithium - faster chunk serialization + private static final ThreadLocal CACHED_ARRAY_4096 = ThreadLocal.withInitial(() -> new short[4096]); + private static final ThreadLocal CACHED_ARRAY_64 = ThreadLocal.withInitial(() -> new short[64]); -+ + private Optional asOptional(long[] data) { + return Optional.of(Arrays.stream(data)); + } -+ + private short[] getOrCreate(int size) { + return switch (size) { + case 64 -> CACHED_ARRAY_64.get(); @@ -115,17 +121,20 @@ index 7da7ce0fd19896593e63edc88b492c02f926bba0..0f89bdb35fced1b9e674959ca510d2da + default -> new short[size]; + }; + } -+ // Leaves end - faster chunk serialization ++ // Gale end - Lithium - faster chunk serialization + private static final int MIN_PALETTE_BITS = 0; private final PaletteResize dummyPaletteResize = (bits, objectAdded) -> 0; public final IdMap registry; -@@ -344,28 +362,76 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -343,28 +359,54 @@ public class PalettedContainer implements PaletteResize, PalettedContainer public synchronized PalettedContainerRO.PackedData pack(IdMap registry, PalettedContainer.Strategy strategy) { // Paper - synchronize this.acquire(); - PalettedContainerRO.PackedData var12; -- try { ++ // Gale start - Lithium - faster chunk serialization ++ Optional data = Optional.empty(); ++ List elements = null; + try { - HashMapPalette hashMapPalette = new HashMapPalette<>(registry, this.data.storage.getBits(), this.dummyPaletteResize); - int size = strategy.size(); - int[] ints = new int[size]; @@ -138,135 +147,92 @@ index 7da7ce0fd19896593e63edc88b492c02f926bba0..0f89bdb35fced1b9e674959ca510d2da - optional = Optional.of(Arrays.stream(simpleBitStorage.getRaw())); - } else { - optional = Optional.empty(); -- } -+ // Leaves start - faster chunk serialization -+ if (!org.leavesmc.leaves.LeavesConfig.performance.fasterChunkSerialization) { -+ PalettedContainerRO.PackedData var12; -+ try { -+ HashMapPalette hashMapPalette = new HashMapPalette<>(registry, this.data.storage.getBits(), this.dummyPaletteResize); -+ int i = strategy.size(); -+ int[] is = new int[i]; -+ this.data.storage.unpack(is); -+ swapPalette(is, (id) -> { -+ return hashMapPalette.idFor(this.data.palette.valueFor(id)); -+ }); -+ int j = strategy.calculateBitsForSerialization(registry, hashMapPalette.getSize()); -+ Optional optional; -+ if (j != 0) { -+ SimpleBitStorage simpleBitStorage = new SimpleBitStorage(j, i, is); -+ optional = Optional.of(Arrays.stream(simpleBitStorage.getRaw())); -+ } else { -+ optional = Optional.empty(); -+ } ++ // The palette that will be serialized ++ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette hashPalette = null; ++ ++ final Palette palette = this.data.palette(); ++ final BitStorage storage = this.data.storage(); ++ if (storage instanceof ZeroBitStorage || palette.getSize() == 1) { ++ // If the palette only contains one entry, don't attempt to repack it. ++ elements = List.of(palette.valueFor(0)); ++ } else if (palette instanceof org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette lithiumHashPalette) { ++ hashPalette = lithiumHashPalette; + } - var12 = new PalettedContainerRO.PackedData<>(hashMapPalette.getEntries(), optional); -- } finally { -- this.release(); -+ var12 = new PalettedContainerRO.PackedData<>(hashMapPalette.getEntries(), optional); -+ } finally { -+ this.release(); -+ } -+ return var12; -+ } else { -+ Optional data = Optional.empty(); -+ List elements = null; -+ try { -+ // The palette that will be serialized -+ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette hashPalette = null; ++ if (elements == null) { ++ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette compactedPalette = new org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<>(registry, storage.getBits(), this.dummyPaletteResize); ++ short[] array = this.getOrCreate(strategy.size()); + -+ final Palette palette = this.data.palette(); -+ final BitStorage storage = this.data.storage(); -+ if (storage instanceof ZeroBitStorage || palette.getSize() == 1) { -+ // If the palette only contains one entry, don't attempt to repack it. -+ elements = List.of(palette.valueFor(0)); -+ } else if (palette instanceof org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette lithiumHashPalette) { -+ hashPalette = lithiumHashPalette; -+ } -+ if (elements == null) { -+ org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette compactedPalette = new org.leavesmc.leaves.lithium.common.world.chunk.LithiumHashPalette<>(registry, storage.getBits(), this.dummyPaletteResize); -+ short[] array = this.getOrCreate(strategy.size()); ++ storage.compact(this.data.palette(), compactedPalette, array); + -+ storage.compact(this.data.palette(), compactedPalette, array); -+ -+ // If the palette didn't change during compaction, do a simple copy of the data array -+ if (hashPalette != null && hashPalette.getSize() == compactedPalette.getSize() && storage.getBits() == strategy.calculateBitsForSerialization(registry, hashPalette.getSize())) { // paletteSize can de-sync from palette - see https://github.com/CaffeineMC/lithium-fabric/issues/279 -+ data = this.asOptional(storage.getRaw().clone()); -+ elements = hashPalette.getElements(); -+ } else { -+ int bits = strategy.calculateBitsForSerialization(registry, compactedPalette.getSize()); -+ if (bits != 0) { -+ // Re-pack the integer array as the palette has changed size -+ SimpleBitStorage copy = new SimpleBitStorage(bits, array.length); -+ for (int i = 0; i < array.length; ++i) { -+ copy.set(i, array[i]); -+ } -+ // We don't need to clone the data array as we are the sole owner of it -+ data = this.asOptional(copy.getRaw()); ++ // If the palette didn't change during compaction, do a simple copy of the data array ++ if (hashPalette != null && hashPalette.getSize() == compactedPalette.getSize() && storage.getBits() == strategy.calculateBitsForSerialization(registry, hashPalette.getSize())) { // paletteSize can de-sync from palette - see https://github.com/CaffeineMC/lithium-fabric/issues/279 ++ data = this.asOptional(storage.getRaw().clone()); ++ elements = hashPalette.getElements(); ++ } else { ++ int bits = strategy.calculateBitsForSerialization(registry, compactedPalette.getSize()); ++ if (bits != 0) { ++ // Re-pack the integer array as the palette has changed size ++ SimpleBitStorage copy = new SimpleBitStorage(bits, array.length); ++ for (int i = 0; i < array.length; ++i) { ++ copy.set(i, array[i]); + } ++ ++ // We don't need to clone the data array as we are the sole owner of it ++ data = this.asOptional(copy.getRaw()); + } ++ + elements = compactedPalette.getElements(); + } -+ } finally { -+ this.release(); + } -+ return new PalettedContainerRO.PackedData<>(elements, data); + } finally { + this.release(); } -- + - return var12; -+ // Leaves end - faster chunk serialization ++ return new PalettedContainerRO.PackedData<>(elements, data); ++ // Gale end - Lithium - faster chunk serialization } private static void swapPalette(int[] bits, IntUnaryOperator operator) { -@@ -405,13 +471,47 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -404,13 +446,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @Override public void count(PalettedContainer.CountConsumer countConsumer) { - if (this.data.palette.getSize() == 1) { - countConsumer.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); -+ // Leaves start - faster chunk serialization -+ if (!org.leavesmc.leaves.LeavesConfig.performance.fasterChunkSerialization) { -+ if (this.data.palette.getSize() == 1) { -+ countConsumer.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); -+ } else { -+ Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap(); -+ this.data.storage.getAll((key) -> { -+ int2IntOpenHashMap.addTo(key, 1); -+ }); -+ int2IntOpenHashMap.int2IntEntrySet().forEach((entry) -> { -+ countConsumer.accept(this.data.palette.valueFor(entry.getIntKey()), entry.getIntValue()); -+ }); -+ } - } else { +- } else { - Int2IntOpenHashMap map = new Int2IntOpenHashMap(); - this.data.storage.getAll(id -> map.addTo(id, 1)); - map.int2IntEntrySet().forEach(idEntry -> countConsumer.accept(this.data.palette.valueFor(idEntry.getIntKey()), idEntry.getIntValue())); -+ int len = this.data.palette().getSize(); ++ // Gale start - Lithium - faster chunk serialization ++ int len = this.data.palette().getSize(); + -+ // Do not allocate huge arrays if we're using a large palette -+ if (len > 4096) { -+ if (this.data.palette.getSize() == 1) { -+ countConsumer.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); -+ } else { -+ Int2IntOpenHashMap int2IntOpenHashMap = new Int2IntOpenHashMap(); -+ this.data.storage.getAll((key) -> { -+ int2IntOpenHashMap.addTo(key, 1); -+ }); -+ int2IntOpenHashMap.int2IntEntrySet().forEach((entry) -> { -+ countConsumer.accept(this.data.palette.valueFor(entry.getIntKey()), entry.getIntValue()); -+ }); -+ } ++ // Do not allocate huge arrays if we're using a large palette ++ if (len > 4096) { ++ // VanillaCopy ++ if (this.data.palette.getSize() == 1) { ++ countConsumer.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); ++ } else { ++ Int2IntOpenHashMap map = new Int2IntOpenHashMap(); ++ this.data.storage.getAll(id -> map.addTo(id, 1)); ++ map.int2IntEntrySet().forEach(idEntry -> countConsumer.accept(this.data.palette.valueFor(idEntry.getIntKey()), idEntry.getIntValue())); + } ++ } + -+ short[] counts = new short[len]; -+ this.data.storage().getAll(i -> counts[i]++); -+ for (int i = 0; i < counts.length; i++) { -+ T obj = this.data.palette().valueFor(i); -+ if (obj != null) { -+ countConsumer.accept(obj, counts[i]); -+ } ++ short[] counts = new short[len]; ++ ++ this.data.storage().getAll(i -> counts[i]++); ++ ++ for (int i = 0; i < counts.length; i++) { ++ T obj = this.data.palette().valueFor(i); ++ ++ if (obj != null) { ++ countConsumer.accept(obj, counts[i]); + } } -+ // Leaves end - faster chunk serialization ++ // Gale end - Lithium - faster chunk serialization } record Configuration(Palette.Factory factory, int bits) { diff --git a/leaves-server/minecraft-patches/features/0063-Optimize-sun-burn-tick.patch b/leaves-server/minecraft-patches/features/0063-Optimize-sun-burn-tick.patch index f9a09bce..54ef9da1 100644 --- a/leaves-server/minecraft-patches/features/0063-Optimize-sun-burn-tick.patch +++ b/leaves-server/minecraft-patches/features/0063-Optimize-sun-burn-tick.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Optimize sun burn tick This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 0c1a50d293638c319b34f757c0ba41d31a1538ac..127d306218247ad7da3ebfff2fc5fd20115da365 100644 +index 0484649d8835e16b71f9ba3e0da16198fa94cb73..2df9769eb76db2fb0e552716183ee1e899a59fbf 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -2038,9 +2038,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2112,9 +2112,20 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Deprecated public float getLightLevelDependentMagicValue() { @@ -33,7 +33,7 @@ index 0c1a50d293638c319b34f757c0ba41d31a1538ac..127d306218247ad7da3ebfff2fc5fd20 } public void absSnapTo(double x, double y, double z, float yRot, float xRot) { -@@ -2055,6 +2066,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2129,6 +2140,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.xRotO = this.getXRot(); this.setYHeadRot(yRot); // Paper - Update head rotation } @@ -42,10 +42,10 @@ index 0c1a50d293638c319b34f757c0ba41d31a1538ac..127d306218247ad7da3ebfff2fc5fd20 public void absSnapTo(double x, double y, double z) { double d = Mth.clamp(x, -3.0E7, 3.0E7); diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index c83ad2553145b66aad000be3b82fec57f56359ce..c7df4f3a9fb1c3e34a737af1c80e62220abf7edb 100644 +index a8bb9822e963d7d8245c8d6589604fd92b424f18..c05803a72b5db05f9a0b6119b57f665a25e1277a 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -1507,17 +1507,39 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1533,17 +1533,39 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab protected void playAttackSound() { } diff --git a/leaves-server/minecraft-patches/features/0067-Check-frozen-ticks-before-landing-block.patch b/leaves-server/minecraft-patches/features/0067-Check-frozen-ticks-before-landing-block.patch index 7ebf4d9d..8a6bb147 100644 --- a/leaves-server/minecraft-patches/features/0067-Check-frozen-ticks-before-landing-block.patch +++ b/leaves-server/minecraft-patches/features/0067-Check-frozen-ticks-before-landing-block.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Check frozen ticks before landing block This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index a95fec1506af042bd3d4424e93aa3f4de9627487..ce624ed17bc5c9b5e13d280f8dda736581b21821 100644 +index c25cdcebfdd2697da927d55420ab9f02bd4c792a..305c099d32f1472a6e8909cdf2a53cec8a31afb5 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -523,10 +523,10 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -537,10 +537,10 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin } protected void tryAddFrost() { diff --git a/leaves-server/minecraft-patches/features/0068-Skip-entity-move-if-movement-is-zero.patch b/leaves-server/minecraft-patches/features/0068-Skip-entity-move-if-movement-is-zero.patch index 4ca3e218..3453da40 100644 --- a/leaves-server/minecraft-patches/features/0068-Skip-entity-move-if-movement-is-zero.patch +++ b/leaves-server/minecraft-patches/features/0068-Skip-entity-move-if-movement-is-zero.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Skip entity move if movement is zero This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 127d306218247ad7da3ebfff2fc5fd20115da365..392c1dd211d901a066dac83f15f03e1738a2478b 100644 +index d293d79db9f58c78b32818834d2636d9f52486ca..39c80b858b6bb94949fb7d2fb8347a7a628cb65f 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -242,6 +242,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -262,6 +262,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public float yRotO; public float xRotO; private AABB bb = INITIAL_AABB; @@ -17,7 +17,7 @@ index 127d306218247ad7da3ebfff2fc5fd20115da365..392c1dd211d901a066dac83f15f03e17 public boolean onGround; public boolean horizontalCollision; public boolean verticalCollision; -@@ -1068,6 +1069,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1094,6 +1095,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - detailed watchdog information public void move(MoverType type, Vec3 movement) { @@ -31,7 +31,7 @@ index 127d306218247ad7da3ebfff2fc5fd20115da365..392c1dd211d901a066dac83f15f03e17 final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity // Paper start - detailed watchdog information ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main"); -@@ -4195,6 +4203,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4415,6 +4423,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public final void setBoundingBox(AABB bb) { diff --git a/leaves-server/minecraft-patches/features/0069-Skip-cloning-advancement-criteria.patch b/leaves-server/minecraft-patches/features/0069-Skip-cloning-advancement-criteria.patch index 786eff64..a4e8fe18 100644 --- a/leaves-server/minecraft-patches/features/0069-Skip-cloning-advancement-criteria.patch +++ b/leaves-server/minecraft-patches/features/0069-Skip-cloning-advancement-criteria.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Skip cloning advancement criteria This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/net/minecraft/advancements/Advancement.java b/net/minecraft/advancements/Advancement.java -index a1abe9a798e459798ac18d8a9b4756c66eba9721..4bd3babe69b516a1f4938cc3b75ef6e4c6fffe55 100644 +index ac6a85ddf6eb326b3fd53341a4a5db7bd00b7ce2..e677a81e7005b5c596a2cef3b14e2c738559e586 100644 --- a/net/minecraft/advancements/Advancement.java +++ b/net/minecraft/advancements/Advancement.java @@ -61,7 +61,7 @@ public record Advancement( diff --git a/leaves-server/minecraft-patches/features/0070-Fix-villagers-dont-release-memory.patch b/leaves-server/minecraft-patches/features/0070-Fix-villagers-dont-release-memory.patch index fd55748e..28135dc9 100644 --- a/leaves-server/minecraft-patches/features/0070-Fix-villagers-dont-release-memory.patch +++ b/leaves-server/minecraft-patches/features/0070-Fix-villagers-dont-release-memory.patch @@ -5,20 +5,20 @@ Subject: [PATCH] Fix villagers dont release memory diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 392c1dd211d901a066dac83f15f03e1738a2478b..0227bb06cfd7d5280a2b7c09e7e659806bedadcd 100644 +index 39c80b858b6bb94949fb7d2fb8347a7a628cb65f..2d97fc7b51f89c323dd893f2407125b1e8bd79fb 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3826,7 +3826,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4032,7 +4032,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this; } -- private Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) { -+ protected Entity teleportCrossDimension(ServerLevel level, TeleportTransition teleportTransition) { // Leaves - private -> protected +- private Entity teleportCrossDimension(ServerLevel oldLevel, ServerLevel newLevel, TeleportTransition teleportTransition) { ++ protected Entity teleportCrossDimension(ServerLevel oldLevel, ServerLevel newLevel, TeleportTransition teleportTransition) { // Leaves - private -> protected List passengers = this.getPassengers(); List list = new ArrayList<>(passengers.size()); this.ejectPassengers(); diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index e0e0d2ea7fc60e3142c675404d152eca60263240..956b949b42a7041290838dde816d3b79e1f9e0d4 100644 +index e1e2bdb35866a8f32a41f6efd24ad77cf916b2e9..22ef2d7bc8f514bf5a7a1f2fdb9a05a256378c5e 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java @@ -1033,4 +1033,19 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -28,7 +28,7 @@ index e0e0d2ea7fc60e3142c675404d152eca60263240..956b949b42a7041290838dde816d3b79 + + // Leaves start - fixes a memory leak when villagers get moved to another world + @Override -+ public Entity teleportCrossDimension(ServerLevel world, net.minecraft.world.level.portal.TeleportTransition transition) { ++ public Entity teleportCrossDimension(ServerLevel oldWorld, ServerLevel newWorld, net.minecraft.world.level.portal.TeleportTransition transition) { + if (org.leavesmc.leaves.LeavesConfig.performance.villagersDontReleaseMemoryFix) { + this.releaseAllPois(); + this.getBrain().eraseMemory(MemoryModuleType.HOME); @@ -37,7 +37,7 @@ index e0e0d2ea7fc60e3142c675404d152eca60263240..956b949b42a7041290838dde816d3b79 + this.getBrain().eraseMemory(MemoryModuleType.MEETING_POINT); + this.refreshBrain(transition.newLevel()); + } -+ return super.teleportCrossDimension(world, transition); ++ return super.teleportCrossDimension(oldWorld, newWorld, transition); + } + // Leaves end - fixes a memory leak when villagers get moved to another world } diff --git a/leaves-server/minecraft-patches/features/0071-Avoid-anvil-too-expensive.patch b/leaves-server/minecraft-patches/features/0071-Avoid-anvil-too-expensive.patch index 6e9ab8ec..83fb2662 100644 --- a/leaves-server/minecraft-patches/features/0071-Avoid-anvil-too-expensive.patch +++ b/leaves-server/minecraft-patches/features/0071-Avoid-anvil-too-expensive.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Avoid anvil too expensive diff --git a/net/minecraft/world/inventory/AnvilMenu.java b/net/minecraft/world/inventory/AnvilMenu.java -index 65c400444314049d5529f1f76d65fbd6b1ea7af2..eed4ba79dd5328a59121bd9fe81ef1efd563094e 100644 +index 2346e1fc0c94084c3bb95c00be8aac36ae5f26ae..fa5fb93e2d3abd7171f4f7db9a74d42ec37b8ecd 100644 --- a/net/minecraft/world/inventory/AnvilMenu.java +++ b/net/minecraft/world/inventory/AnvilMenu.java -@@ -259,7 +259,7 @@ public class AnvilMenu extends ItemCombinerMenu { +@@ -266,7 +266,7 @@ public class AnvilMenu extends ItemCombinerMenu { this.onlyRenaming = true; } diff --git a/leaves-server/minecraft-patches/features/0072-Bow-infinity-fix.patch b/leaves-server/minecraft-patches/features/0072-Bow-infinity-fix.patch index baa38a1f..92737da6 100644 --- a/leaves-server/minecraft-patches/features/0072-Bow-infinity-fix.patch +++ b/leaves-server/minecraft-patches/features/0072-Bow-infinity-fix.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bow infinity fix diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index ee8c0d0edbb296106a128c48f4186ba3a5bf9df8..6c32b0e26a77c808fb16fc420e89fcebbea56ab1 100644 +index 0abdf0e520d1a0672917d60b79f467df4399e256..1ba438f338d53c24f9c85353adacab5699c19aae 100644 --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java -@@ -2169,8 +2169,10 @@ public abstract class Player extends LivingEntity { +@@ -2187,8 +2187,10 @@ public abstract class Player extends LivingEntity { } } diff --git a/leaves-server/minecraft-patches/features/0073-Zero-tick-plants.patch b/leaves-server/minecraft-patches/features/0073-Zero-tick-plants.patch index a8b2b7f8..bd20206a 100644 --- a/leaves-server/minecraft-patches/features/0073-Zero-tick-plants.patch +++ b/leaves-server/minecraft-patches/features/0073-Zero-tick-plants.patch @@ -20,7 +20,7 @@ index a6249f5852c4ac2432bb60cb4f7a2e0a03abd7dd..29f9866e693dbbf9487cdc15ca8d2f55 } diff --git a/net/minecraft/world/level/block/CactusBlock.java b/net/minecraft/world/level/block/CactusBlock.java -index 8f6878cc8e72513446895bfc79886075bfcd5565..efbd3aff528cd81a79c522aa44b6348827b8c88d 100644 +index d4fbf130e23a959be8268085067b3bea1541be9a..a8cb3264ebc3b9728ce1a1af449f7ccb4d3c9973 100644 --- a/net/minecraft/world/level/block/CactusBlock.java +++ b/net/minecraft/world/level/block/CactusBlock.java @@ -47,6 +47,10 @@ public class CactusBlock extends Block { diff --git a/leaves-server/minecraft-patches/features/0074-Replay-Mod-API.patch b/leaves-server/minecraft-patches/features/0074-Replay-Mod-API.patch index 26704277..68f08dcf 100644 --- a/leaves-server/minecraft-patches/features/0074-Replay-Mod-API.patch +++ b/leaves-server/minecraft-patches/features/0074-Replay-Mod-API.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Replay Mod API This patch is Powered by ReplayMod(https://github.com/ReplayMod) diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java -index cb63e4c264a31788cd1405428af70f7a018910e9..a1e8f25b70b49590fd42b618fcd467cf306650af 100644 +index 3acfb2a78845dd8081dc3c01d653034232c76e60..efe3f1849e68e5bbe2cdb3793dafc8b58c3d8415 100644 --- a/net/minecraft/commands/CommandSourceStack.java +++ b/net/minecraft/commands/CommandSourceStack.java -@@ -588,7 +588,7 @@ public class CommandSourceStack implements ExecutionCommandSource getOnlinePlayerNames() { @@ -81,10 +81,10 @@ index 514f8fbdeb776087608665c35de95294aadf5cf0..2f78ca86f46ea08fdcf4b8047d3d0b04 if (players.size() >= resultLimit) { return players; diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index ca4fdcabbe6c0c57bfa13ef6d83bcd560baae8fc..2005719308a281128a5edc24a563df929418c6e3 100644 +index a9322925daca18b3f3120bd540c47b4758b1ecf7..57b0ec8336722197dae868d92d8733330f0b0722 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1637,7 +1637,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - PlayerList playerList = context.getSource().getServer().getPlayerList(); + (commandContext, suggestionsBuilder) -> { + PlayerList playerList = commandContext.getSource().getServer().getPlayerList(); return SharedSuggestionProvider.suggest( - playerList.getPlayers() + playerList.realPlayers // Leaves - only real player .stream() - .filter(player -> !playerList.isOp(player.getGameProfile())) - .map(player -> player.getGameProfile().getName()), + .filter(serverPlayer -> !playerList.isOp(serverPlayer.getGameProfile())) + .map(serverPlayer -> serverPlayer.getGameProfile().getName()), diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 68490d8dc26c2d5f4999361fd7ad72a83581f48f..122e5e46a2c1e4be5c9d04501bfe064f239ec230 100644 +index e6de7ef46d197c14495d4b55d094af34816fc063..5072dc7ac71e1640b2aad35c3c3560e0860ece94 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -2645,7 +2645,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2693,7 +2693,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (entity instanceof ServerPlayer serverPlayer) { ServerLevel.this.players.add(serverPlayer); // Leaves start - skip @@ -132,7 +132,7 @@ index 68490d8dc26c2d5f4999361fd7ad72a83581f48f..122e5e46a2c1e4be5c9d04501bfe064f ServerLevel.this.realPlayers.add(serverPlayer); } // Leaves end - skip -@@ -2720,7 +2720,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2776,7 +2776,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (entity instanceof ServerPlayer serverPlayer) { ServerLevel.this.players.remove(serverPlayer); // Leaves start - skip @@ -142,10 +142,10 @@ index 68490d8dc26c2d5f4999361fd7ad72a83581f48f..122e5e46a2c1e4be5c9d04501bfe064f } // Leaves end - skip diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 72c2762485da81d3a252290455f57a8cf81dfe66..0dee4945feb6d4cb2f520d346bf8be4fa36fb868 100644 +index 318ce28d0eb6373ecfb2f15d210085f8156ff8c7..de411c04a010d8d2b091b9060d42d4074a6712c8 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -131,6 +131,7 @@ public abstract class PlayerList { +@@ -130,6 +130,7 @@ public abstract class PlayerList { private boolean allowCommandsForAllPlayers; private static final boolean ALLOW_LOGOUTIVATOR = false; private int sendAllPlayerInfoIn; @@ -153,7 +153,7 @@ index 72c2762485da81d3a252290455f57a8cf81dfe66..0dee4945feb6d4cb2f520d346bf8be4f // CraftBukkit start private org.bukkit.craftbukkit.CraftServer cserver; -@@ -149,6 +150,119 @@ public abstract class PlayerList { +@@ -148,6 +149,125 @@ public abstract class PlayerList { abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor @@ -235,6 +235,12 @@ index 72c2762485da81d3a252290455f57a8cf81dfe66..0dee4945feb6d4cb2f520d346bf8be4f + continue; + } + ++ // Leaves start - skip photographer ++ if (entityplayer1 instanceof org.leavesmc.leaves.replay.ServerPhotographer) { ++ continue; ++ } ++ // Leaves end - skip photographer ++ + onlinePlayers.add(entityplayer1); + } + if (!onlinePlayers.isEmpty()) { @@ -252,7 +258,7 @@ index 72c2762485da81d3a252290455f57a8cf81dfe66..0dee4945feb6d4cb2f520d346bf8be4f + this.server.getCustomBossEvents().onPlayerConnect(player); + } + -+ worldserver1 = player.serverLevel(); ++ worldserver1 = player.level(); + java.util.Iterator iterator = player.getActiveEffects().iterator(); + while (iterator.hasNext()) { + MobEffectInstance mobeffect = iterator.next(); @@ -273,34 +279,21 @@ index 72c2762485da81d3a252290455f57a8cf81dfe66..0dee4945feb6d4cb2f520d346bf8be4f public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie cookie) { player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed -@@ -309,6 +423,7 @@ public abstract class PlayerList { +@@ -310,6 +430,7 @@ public abstract class PlayerList { - // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below - this.players.add(player); -+ this.realPlayers.add(player); // Leaves - replay api - this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot - this.playersByUUID.put(player.getUUID(), player); - // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below -@@ -383,6 +498,12 @@ public abstract class PlayerList { - continue; - } - -+ // Leaves start - skip photographer -+ if (entityplayer1 instanceof org.leavesmc.leaves.replay.ServerPhotographer) { -+ continue; -+ } -+ // Leaves end - skip photographer -+ - onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join - } - // Paper start - Use single player info update packet on join + // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below + this.players.add(player); ++ this.realPlayers.add(player); // Leaves - replay api + this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot + this.playersByUUID.put(player.getUUID(), player); + // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below @@ -517,6 +638,43 @@ public abstract class PlayerList { } } + // Leaves start - replay mod api + public void removePhotographer(org.leavesmc.leaves.replay.ServerPhotographer entityplayer) { -+ ServerLevel worldserver = entityplayer.serverLevel(); ++ ServerLevel worldserver = entityplayer.level(); + + entityplayer.awardStat(Stats.LEAVE_GAME); + @@ -346,12 +339,12 @@ index 72c2762485da81d3a252290455f57a8cf81dfe66..0dee4945feb6d4cb2f520d346bf8be4f this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot this.server.getCustomBossEvents().onPlayerDisconnect(player); UUID uuid = player.getUUID(); -@@ -683,7 +842,7 @@ public abstract class PlayerList { - // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile) - // ? Component.translatable("multiplayer.disconnect.server_full") - // : null; -- if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) { -+ if (this.realPlayers.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) { // Leaves - only real player - event.disallow(org.bukkit.event.player.PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure - } - } +@@ -1032,7 +1191,7 @@ public abstract class PlayerList { + + // Paper start - whitelist verify event / login event + public LoginResult canBypassFullServerLogin(final GameProfile profile, final LoginResult currentResult) { +- final boolean shouldKick = this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(profile); ++ final boolean shouldKick = this.realPlayers.size() >= this.maxPlayers && !this.canBypassPlayerLimit(profile); // Leaves - only real player + final io.papermc.paper.event.player.PlayerServerFullCheckEvent fullCheckEvent = new io.papermc.paper.event.player.PlayerServerFullCheckEvent( + com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitMirror(profile), + io.papermc.paper.adventure.PaperAdventure.asAdventure(currentResult.message), diff --git a/leaves-server/minecraft-patches/features/0075-Leaves-I18n-support.patch b/leaves-server/minecraft-patches/features/0075-Leaves-I18n-support.patch index a3eca868..a4039032 100644 --- a/leaves-server/minecraft-patches/features/0075-Leaves-I18n-support.patch +++ b/leaves-server/minecraft-patches/features/0075-Leaves-I18n-support.patch @@ -26,10 +26,10 @@ index 7b9e2a1a208b46a69c16e6afd8b502259893574f..8ef3627217a8c495e4e31b70e61ad1b7 loadFromJson(resourceAsStream, output); } catch (JsonParseException | IOException var7) { diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 4cde785a679dccc3dfa42272e6094328e9ce98c1..3efcacd808d968b7ff3a67b05d9fcd4e7dc21236 100644 +index e673df664b06c654a7be0622874b9b27ad7ef20f..898bf4d1e3269135f9514cdfd923040b947eef33 100644 --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -153,6 +153,8 @@ public class Main { +@@ -154,6 +154,8 @@ public class Main { return; } @@ -39,13 +39,13 @@ index 4cde785a679dccc3dfa42272e6094328e9ce98c1..3efcacd808d968b7ff3a67b05d9fcd4e String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck(); if (awtException != null) { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 9543e374f779e0488cf876aff546c475c3dfc0c3..12c8486ff2a5a7140fde40babc4388f311a6401e 100644 +index 91babab6152bb12768399ef6f2ea6afcb5e644b7..bb6863ed3fdb7bcf73ddecc1a93f89d5f84b728e 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -186,6 +186,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface - com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now +@@ -187,6 +187,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface org.leavesmc.leaves.LeavesConfig.init((java.io.File) options.valueOf("leaves-settings")); // Leaves - Server Config + this.getBotList().loadBotInfo(); // Leaves - load resident bot info + org.leavesmc.leaves.util.ServerI18nUtil.init(); // Leaves I18n com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics // Leaves - down diff --git a/leaves-server/minecraft-patches/features/0076-Fix-minecraft-hopper-not-work-without-player.patch b/leaves-server/minecraft-patches/features/0076-Fix-minecraft-hopper-not-work-without-player.patch index 00cd4117..f3d662b7 100644 --- a/leaves-server/minecraft-patches/features/0076-Fix-minecraft-hopper-not-work-without-player.patch +++ b/leaves-server/minecraft-patches/features/0076-Fix-minecraft-hopper-not-work-without-player.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix minecraft hopper not work without player diff --git a/net/minecraft/world/entity/vehicle/MinecartHopper.java b/net/minecraft/world/entity/vehicle/MinecartHopper.java -index a56d9cdeb6589a053ffaaf2cd599a98ae0a0989a..eb94eb2fe717f6432e458deefb39f37600d890fc 100644 +index 41a6ec508a10a49a37539d2f10171d15c233b280..ae6246635b7961b91a217b7f4f9d9d0f41560207 100644 --- a/net/minecraft/world/entity/vehicle/MinecartHopper.java +++ b/net/minecraft/world/entity/vehicle/MinecartHopper.java -@@ -100,6 +100,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -101,6 +101,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper } } diff --git a/leaves-server/minecraft-patches/features/0077-RNG-Fishing.patch b/leaves-server/minecraft-patches/features/0077-RNG-Fishing.patch index ec1da438..107f3a39 100644 --- a/leaves-server/minecraft-patches/features/0077-RNG-Fishing.patch +++ b/leaves-server/minecraft-patches/features/0077-RNG-Fishing.patch @@ -5,10 +5,10 @@ Subject: [PATCH] RNG Fishing diff --git a/net/minecraft/world/entity/projectile/FishingHook.java b/net/minecraft/world/entity/projectile/FishingHook.java -index f82f37d498f99ce38f72a63d051721c6dab9f2ca..0014ede48956facc87940f4b1d5f8ac72af052bb 100644 +index 8c139d572bd3c44b8e2b6205e28ab09f82c9abfe..a5df132c2d97c30ad0960197ea7ce8640ee9e863 100644 --- a/net/minecraft/world/entity/projectile/FishingHook.java +++ b/net/minecraft/world/entity/projectile/FishingHook.java -@@ -518,7 +518,7 @@ public class FishingHook extends Projectile { +@@ -529,7 +529,7 @@ public class FishingHook extends Projectile { .withLuck(this.luck + playerOwner.getLuck()) .create(LootContextParamSets.FISHING); LootTable lootTable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING); diff --git a/leaves-server/minecraft-patches/features/0078-Wool-Hopper-Counter.patch b/leaves-server/minecraft-patches/features/0078-Wool-Hopper-Counter.patch index 6dc4546f..85b9b0d3 100644 --- a/leaves-server/minecraft-patches/features/0078-Wool-Hopper-Counter.patch +++ b/leaves-server/minecraft-patches/features/0078-Wool-Hopper-Counter.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Wool Hopper Counter This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index a2fe5fdf50ae731e423821a0d1c52141b478e0be..7140571ef324f823942bc2c528cb66dac9e91d94 100644 +index ea64414708d7034ccbc0e93a344d17c851f78add..47281ac61c6a462a47c60cc51f48440d3691effd 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -432,6 +432,13 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen diff --git a/leaves-server/minecraft-patches/features/0079-Spider-jockeys-drop-gapples.patch b/leaves-server/minecraft-patches/features/0079-Spider-jockeys-drop-gapples.patch index afcde1f9..c4829040 100644 --- a/leaves-server/minecraft-patches/features/0079-Spider-jockeys-drop-gapples.patch +++ b/leaves-server/minecraft-patches/features/0079-Spider-jockeys-drop-gapples.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Spider jockeys drop gapples diff --git a/net/minecraft/world/entity/monster/Skeleton.java b/net/minecraft/world/entity/monster/Skeleton.java -index 48f26ed693b43e3f65f1559ba69b3d7249664f71..7ee1aa2d41cadefb0ee0a5f17a04ed52da60de86 100644 +index 743bc2986b962d4aaef00d2e457117f375ca65c7..7a982b5720278ad6870446bfc1cffb220d08279e 100644 --- a/net/minecraft/world/entity/monster/Skeleton.java +++ b/net/minecraft/world/entity/monster/Skeleton.java -@@ -139,4 +139,16 @@ public class Skeleton extends AbstractSkeleton { +@@ -140,4 +140,16 @@ public class Skeleton extends AbstractSkeleton { this.spawnAtLocation(level, Items.SKELETON_SKULL); } } diff --git a/leaves-server/minecraft-patches/features/0080-Force-Void-Trade.patch b/leaves-server/minecraft-patches/features/0080-Force-Void-Trade.patch index 8196aa70..c5705505 100644 --- a/leaves-server/minecraft-patches/features/0080-Force-Void-Trade.patch +++ b/leaves-server/minecraft-patches/features/0080-Force-Void-Trade.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Force Void Trade diff --git a/net/minecraft/world/entity/npc/AbstractVillager.java b/net/minecraft/world/entity/npc/AbstractVillager.java -index a375fad192cc09ba83775d5e37c1bb351730e6c4..203e6819aa39de7e932125acb8a0de224918bb6f 100644 +index 38572ecba568072b132b9e7fc12e6c0c38edd2e2..c3bec7a52f167a5169f96da709bcf9269a5bbae1 100644 --- a/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/net/minecraft/world/entity/npc/AbstractVillager.java @@ -43,6 +43,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -74,7 +74,7 @@ index a375fad192cc09ba83775d5e37c1bb351730e6c4..203e6819aa39de7e932125acb8a0de22 + // Leaves end - force void trade } diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 956b949b42a7041290838dde816d3b79e1f9e0d4..1b906f04852637046f03d71f54f950f04c086c46 100644 +index 2330415f8e3bc021e43facff4c99177cc0c9fc5c..cab1ef5547d6de724c4d9341ecad0bff25c84c5b 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java @@ -383,6 +383,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -101,10 +101,10 @@ index 956b949b42a7041290838dde816d3b79e1f9e0d4..1b906f04852637046f03d71f54f950f0 this.updateMerchantTimer = 40; this.increaseProfessionLevelOnUpdate = true; diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index 70cc20483905d3877e2ffb51afb4902bd59f0cd0..066d18609f7f8aa5c14e95e09b454cb7d15f2ed7 100644 +index c2573946dd1244eb5d1ef2be7823211064daa80d..567c24f7c87a23a11c54be1dad531f29d2b3a569 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -123,9 +123,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -124,9 +124,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill return InteractionResult.CONSUME; } @@ -132,7 +132,7 @@ index 1bf2a015fa35981328c098f2fec363c84b85b2a7..8aa4079e7fb5fb81f33859d106a425d0 private int merchantLevel; private boolean showProgressBar; diff --git a/net/minecraft/world/item/trading/MerchantOffer.java b/net/minecraft/world/item/trading/MerchantOffer.java -index 9333c63f217e1207eced37c5be150e192f2fcc3e..0b1a086d3f101b42d95304c69f9e69f4c6c7d906 100644 +index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..a7799f226d7b7d75c5626d6d3d8394f40af930c5 100644 --- a/net/minecraft/world/item/trading/MerchantOffer.java +++ b/net/minecraft/world/item/trading/MerchantOffer.java @@ -39,6 +39,7 @@ public class MerchantOffer { @@ -151,7 +151,7 @@ index 9333c63f217e1207eced37c5be150e192f2fcc3e..0b1a086d3f101b42d95304c69f9e69f4 } public MerchantOffer(ItemCost baseCostA, ItemStack result, int maxUses, int xp, float priceMultiplier) { -@@ -166,6 +168,16 @@ public class MerchantOffer { +@@ -167,6 +169,16 @@ public class MerchantOffer { this.uses++; } @@ -168,7 +168,7 @@ index 9333c63f217e1207eced37c5be150e192f2fcc3e..0b1a086d3f101b42d95304c69f9e69f4 public int getDemand() { return this.demand; } -@@ -195,7 +207,7 @@ public class MerchantOffer { +@@ -196,7 +208,7 @@ public class MerchantOffer { } public boolean isOutOfStock() { diff --git a/leaves-server/minecraft-patches/features/0084-Armor-stand-cant-kill-by-mob-projectile.patch b/leaves-server/minecraft-patches/features/0083-Armor-stand-cant-kill-by-mob-projectile.patch similarity index 89% rename from leaves-server/minecraft-patches/features/0084-Armor-stand-cant-kill-by-mob-projectile.patch rename to leaves-server/minecraft-patches/features/0083-Armor-stand-cant-kill-by-mob-projectile.patch index 8a2efc45..60977a4e 100644 --- a/leaves-server/minecraft-patches/features/0084-Armor-stand-cant-kill-by-mob-projectile.patch +++ b/leaves-server/minecraft-patches/features/0083-Armor-stand-cant-kill-by-mob-projectile.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Armor stand cant kill by mob projectile diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java -index f09bf1f8b23aae530b14129b7a56c96285ef2cf1..a09bd2121d457cace3e38f321985cff8817b2a2f 100644 +index d7725b5ca689e3d5b512baab04e113be77c0b2ee..39b056d73bbdd06ba5cdb5368efcbcc128dc79ae 100644 --- a/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -414,6 +414,15 @@ public class ArmorStand extends LivingEntity { +@@ -372,6 +372,15 @@ public class ArmorStand extends LivingEntity { // CraftBukkit end boolean isCanBreakArmorStand = damageSource.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); boolean isAlwaysKillsArmorStands = damageSource.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); diff --git a/leaves-server/minecraft-patches/features/0083-Disable-offline-warn-if-use-proxy.patch b/leaves-server/minecraft-patches/features/0084-Disable-offline-warn-if-use-proxy.patch similarity index 88% rename from leaves-server/minecraft-patches/features/0083-Disable-offline-warn-if-use-proxy.patch rename to leaves-server/minecraft-patches/features/0084-Disable-offline-warn-if-use-proxy.patch index 8b8e2aa1..ca011833 100644 --- a/leaves-server/minecraft-patches/features/0083-Disable-offline-warn-if-use-proxy.patch +++ b/leaves-server/minecraft-patches/features/0084-Disable-offline-warn-if-use-proxy.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable offline warn if use proxy diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index 12c8486ff2a5a7140fde40babc4388f311a6401e..6846570f8e669341662b86cd9b693aa5fffc897e 100644 +index bb6863ed3fdb7bcf73ddecc1a93f89d5f84b728e..6a6209750854f5bad7f069cd6694d339bd9ce834 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java -@@ -246,7 +246,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -247,7 +247,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord"; String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/"; // Paper end - Add Velocity IP Forwarding Support diff --git a/leaves-server/minecraft-patches/features/0085-Make-Item-tick-vanilla.patch b/leaves-server/minecraft-patches/features/0085-Make-Item-tick-vanilla.patch index 22d6f7dd..46f2ed06 100644 --- a/leaves-server/minecraft-patches/features/0085-Make-Item-tick-vanilla.patch +++ b/leaves-server/minecraft-patches/features/0085-Make-Item-tick-vanilla.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Make Item tick vanilla diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index 0cb2d5cd37171cd6e01748ed3d2ce99da1a15e3f..71c5dd7e58ecc3f4dce0c942a8ce88cb8898cf99 100644 +index 7040d2212f20bb2cd83198b6886074a6f430ee71..351a5fbc4b73098c321ad63119d0515de2271dd9 100644 --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -140,6 +140,9 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -138,6 +138,9 @@ public class ItemEntity extends Entity implements TraceableEntity { // Paper start - EAR 2 @Override public void inactiveTick() { @@ -18,7 +18,7 @@ index 0cb2d5cd37171cd6e01748ed3d2ce99da1a15e3f..71c5dd7e58ecc3f4dce0c942a8ce88cb super.inactiveTick(); if (this.pickupDelay > 0 && this.pickupDelay != 32767) { this.pickupDelay--; -@@ -157,6 +160,8 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -155,6 +158,8 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit end this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } diff --git a/leaves-server/minecraft-patches/features/0088-More-Region-Format-Support.patch b/leaves-server/minecraft-patches/features/0088-More-Region-Format-Support.patch index 37db07b3..37627a15 100644 --- a/leaves-server/minecraft-patches/features/0088-More-Region-Format-Support.patch +++ b/leaves-server/minecraft-patches/features/0088-More-Region-Format-Support.patch @@ -21,7 +21,7 @@ index a814512fcfb85312474ae2c2c21443843bf57831..2b0349568f38321c893a8ffa16607350 public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( final int chunkX, final int chunkZ, final CompoundTag compound diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java -index 709df35246fb328cda21679b53d44d9f96206cb3..8fa38dcff5987e109423a2ed0a86abc9c5c195cd 100644 +index f5ed467c0880e4bcdf1b9ae773a5aac21c4381c3..349741f48bf21777b640a4698a0ae8da0b2487c5 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java @@ -1260,7 +1260,7 @@ public final class MoonriseRegionFileIO { @@ -54,10 +54,10 @@ index 51c126735ace8fdde89ad97b5cab62f244212db0..a6573e327ace16b7ea320eb1440ffcbc + public void moonrise$write(final org.leavesmc.leaves.region.IRegionFile regionFile) throws IOException; // Leaves - more region format } diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 2005719308a281128a5edc24a563df929418c6e3..f1681577f27a618338cae1634094e728c98fc3ff 100644 +index 57b0ec8336722197dae868d92d8733330f0b0722..d2f98398492b74de6a03dbd2cc8f431ddb90867b 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -943,10 +943,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, AutoCl diff --git a/leaves-server/minecraft-patches/features/0095-Vanilla-hopper.patch b/leaves-server/minecraft-patches/features/0095-Vanilla-hopper.patch index d754933e..8b75725c 100644 --- a/leaves-server/minecraft-patches/features/0095-Vanilla-hopper.patch +++ b/leaves-server/minecraft-patches/features/0095-Vanilla-hopper.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Vanilla hopper This is a temporary solution designed to attempt to restore the vanilla behavior of the funnel while preserving optimizations as much as possible. It should ultimately be replaced by the optimization solution provided by lithium. diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 7140571ef324f823942bc2c528cb66dac9e91d94..93dc766b1c4093b1d2bdf7f97951ea82a51cf4e4 100644 +index 47281ac61c6a462a47c60cc51f48440d3691effd..86d14299f7c3b0ba52adebdad07f14fc46f794dd 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -285,36 +285,48 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen diff --git a/leaves-server/minecraft-patches/features/0096-Old-hopper-suckin-behavior.patch b/leaves-server/minecraft-patches/features/0096-Old-hopper-suckin-behavior.patch index dfad3219..e47b526e 100644 --- a/leaves-server/minecraft-patches/features/0096-Old-hopper-suckin-behavior.patch +++ b/leaves-server/minecraft-patches/features/0096-Old-hopper-suckin-behavior.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Old hopper suckin behavior diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 93dc766b1c4093b1d2bdf7f97951ea82a51cf4e4..4d270a77cbb043e16360ae1f2bf03bf0ae32eb38 100644 +index 86d14299f7c3b0ba52adebdad07f14fc46f794dd..44f442c301dff256d7b328f87d6d9ff3a086fed0 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -597,7 +597,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -13,7 +13,7 @@ index 93dc766b1c4093b1d2bdf7f97951ea82a51cf4e4..4d270a77cbb043e16360ae1f2bf03bf0 return false; } else { - boolean flag = hopper.isGridAligned() && blockState.isCollisionShapeFullBlock(level, blockPos) && !blockState.is(BlockTags.DOES_NOT_BLOCK_HOPPERS); -+ boolean flag = hopper.isGridAligned() && (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldHopperSuckInBehavior || blockState.isCollisionShapeFullBlock(level, blockPos)) && !blockState.is(BlockTags.DOES_NOT_BLOCK_HOPPERS); // Leaves - oldHopperSuckInBehavior ++ boolean flag = hopper.isGridAligned() && (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldHopperSuckInBehavior && blockState.isCollisionShapeFullBlock(level, blockPos)) && !blockState.is(BlockTags.DOES_NOT_BLOCK_HOPPERS); // Leaves - oldHopperSuckInBehavior if (!flag) { for (ItemEntity itemEntity : getItemsAtAndAbove(level, hopper)) { if (addItem(hopper, itemEntity)) { diff --git a/leaves-server/minecraft-patches/features/0097-Fix-falling-block-s-block-location.patch b/leaves-server/minecraft-patches/features/0097-Fix-falling-block-s-block-location.patch index 48a053a2..4d2b9bc1 100644 --- a/leaves-server/minecraft-patches/features/0097-Fix-falling-block-s-block-location.patch +++ b/leaves-server/minecraft-patches/features/0097-Fix-falling-block-s-block-location.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix falling block's block location diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 0227bb06cfd7d5280a2b7c09e7e659806bedadcd..c7b085ac004f6be4e10ae929d2fed47dd916e2c9 100644 +index 2d97fc7b51f89c323dd893f2407125b1e8bd79fb..7039619c240a582be1ade95f495042134d6acf68 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -4822,6 +4822,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5020,6 +5020,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess int floor = Mth.floor(x); int floor1 = Mth.floor(y); int floor2 = Mth.floor(z); diff --git a/leaves-server/minecraft-patches/features/0098-Bytebuf-API.patch b/leaves-server/minecraft-patches/features/0098-Bytebuf-API.patch index 6a19d37c..533baada 100644 --- a/leaves-server/minecraft-patches/features/0098-Bytebuf-API.patch +++ b/leaves-server/minecraft-patches/features/0098-Bytebuf-API.patch @@ -4,34 +4,21 @@ Date: Thu, 6 Feb 2025 00:14:22 +0800 Subject: [PATCH] Bytebuf API -diff --git a/net/minecraft/network/chat/Component.java b/net/minecraft/network/chat/Component.java -index c6e4f72825c868b416ce2e81fc6d9b5bfdbd85f2..5c4d0a9297387503f48cb4c1d6db6aedc6ad8258 100644 ---- a/net/minecraft/network/chat/Component.java -+++ b/net/minecraft/network/chat/Component.java -@@ -248,7 +248,7 @@ public interface Component extends Message, FormattedText, Iterable { - .getOrThrow(JsonParseException::new); - } - -- static JsonElement serialize(Component component, HolderLookup.Provider provider) { -+ public static JsonElement serialize(Component component, HolderLookup.Provider provider) { // Leaves - package -> public - return ComponentSerialization.CODEC - .encodeStart(provider.createSerializationContext(JsonOps.INSTANCE), component) - .getOrThrow(JsonParseException::new); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 0dee4945feb6d4cb2f520d346bf8be4fa36fb868..df58e2cd1a8be7c4b24a747ca40d0e79bf40f976 100644 +index de411c04a010d8d2b091b9060d42d4074a6712c8..1d370d5fc9f69bcf2f7087373e9b53fbac792821 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -377,6 +377,13 @@ public abstract class PlayerList { - boolean _boolean = gameRules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); - boolean _boolean1 = gameRules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); - boolean _boolean2 = gameRules.getBoolean(GameRules.RULE_LIMITED_CRAFTING); +@@ -384,6 +384,13 @@ public abstract class PlayerList { + boolean _boolean = gameRules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); + boolean _boolean1 = gameRules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); + boolean _boolean2 = gameRules.getBoolean(GameRules.RULE_LIMITED_CRAFTING); + -+ // Leaves start - Bytebuf API -+ if (!(player instanceof org.leavesmc.leaves.bot.ServerBot) && !(player instanceof org.leavesmc.leaves.replay.ServerPhotographer)) { -+ this.cserver.getBytebufHandler().injectPlayer(player); -+ } -+ // Leaves end - Bytebuf API ++ // Leaves start - Bytebuf API ++ if (!(player instanceof org.leavesmc.leaves.bot.ServerBot) && !(player instanceof org.leavesmc.leaves.replay.ServerPhotographer)) { ++ this.cserver.getBytebufHandler().injectPlayer(player); ++ } ++ // Leaves end - Bytebuf API + - serverGamePacketListenerImpl.send( - new ClientboundLoginPacket( - player.getId(), + serverGamePacketListenerImpl.send( + new ClientboundLoginPacket( + player.getId(), diff --git a/leaves-server/minecraft-patches/features/0099-Allow-grindstone-overstacking.patch b/leaves-server/minecraft-patches/features/0099-Allow-grindstone-overstacking.patch index f181dd14..c63a5041 100644 --- a/leaves-server/minecraft-patches/features/0099-Allow-grindstone-overstacking.patch +++ b/leaves-server/minecraft-patches/features/0099-Allow-grindstone-overstacking.patch @@ -4,11 +4,62 @@ Date: Wed, 26 Jun 2024 17:59:56 +0800 Subject: [PATCH] Allow grindstone overstacking +diff --git a/net/minecraft/world/SimpleContainer.java b/net/minecraft/world/SimpleContainer.java +index 75170c8d3be477a6ea2a1d62018a6ab630b0e54e..e5f348daf1ae9e604ae12928e5c8618c4803bd70 100644 +--- a/net/minecraft/world/SimpleContainer.java ++++ b/net/minecraft/world/SimpleContainer.java +@@ -211,6 +211,12 @@ public class SimpleContainer implements Container, StackedContentsCompatible { + @Override + public void setItem(int index, ItemStack stack) { + this.items.set(index, stack); ++ // Leaves end - grindstone overstacking ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && org.leavesmc.leaves.util.ItemOverstackUtils.CurseEnchantedBook.isCursedEnchantedBook(stack)) { ++ this.setChanged(); ++ return; ++ } ++ // Leaves end - grindstone overstacking + stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util + this.setChanged(); + } +diff --git a/net/minecraft/world/entity/vehicle/ContainerEntity.java b/net/minecraft/world/entity/vehicle/ContainerEntity.java +index 99f109e2653eff10c011f380694bd77a76381cee..3d7ea706747a6bcd8db8dd62139989669acb9c08 100644 +--- a/net/minecraft/world/entity/vehicle/ContainerEntity.java ++++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java +@@ -163,6 +163,11 @@ public interface ContainerEntity extends Container, MenuProvider { + default void setChestVehicleItem(int slot, ItemStack stack) { + this.unpackChestVehicleLootTable(null); + this.getItemStacks().set(slot, stack); ++ // Leaves end - grindstone overstacking ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && org.leavesmc.leaves.util.ItemOverstackUtils.CurseEnchantedBook.isCursedEnchantedBook(stack)) { ++ return; ++ } ++ // Leaves end - grindstone overstacking + stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util + } + diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java -index 8aa689129334f75986fb7a18895e2c3fb3c365c8..3686a28bacf267e4be4fa36f6482ac416c2873ee 100644 +index 863b9ab56304a58e8ecbe43657857b95a19cea87..5e0cd62bd693de025fb4cc70b8f31972f5fe531a 100644 --- a/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -754,10 +754,15 @@ public abstract class AbstractContainerMenu { +@@ -607,7 +607,7 @@ public abstract class AbstractContainerMenu { + } else if (carried.isEmpty()) { + if (slot.mayPlace(item)) { + int maxStackSize = slot.getMaxStackSize(item); +- if (item.getCount() > maxStackSize) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && item.getCount() > maxStackSize) { // Leaves - grindstone overstacking + slot.setByPlayer(item.split(maxStackSize)); + } else { + inventory.setItem(button, ItemStack.EMPTY); +@@ -616,7 +616,7 @@ public abstract class AbstractContainerMenu { + } + } else if (slot.mayPickup(player) && slot.mayPlace(item)) { + int maxStackSize = slot.getMaxStackSize(item); +- if (item.getCount() > maxStackSize) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && item.getCount() > maxStackSize) { // Leaves - grindstone overstacking + slot.setByPlayer(item.split(maxStackSize)); + slot.onTake(player, carried); + if (!inventory.add(carried)) { +@@ -776,10 +776,15 @@ public abstract class AbstractContainerMenu { public abstract boolean stillValid(Player player); protected boolean moveItemStackTo(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection) { @@ -24,7 +75,7 @@ index 8aa689129334f75986fb7a18895e2c3fb3c365c8..3686a28bacf267e4be4fa36f6482ac41 if (isCheck) { stack = stack.copy(); } -@@ -822,6 +827,14 @@ public abstract class AbstractContainerMenu { +@@ -844,6 +849,14 @@ public abstract class AbstractContainerMenu { // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent if (itemx.isEmpty() && slotx.mayPlace(stack)) { int i1 = slotx.getMaxStackSize(stack); @@ -40,7 +91,7 @@ index 8aa689129334f75986fb7a18895e2c3fb3c365c8..3686a28bacf267e4be4fa36f6482ac41 if (isCheck) { stack.shrink(Math.min(stack.getCount(), i1)); diff --git a/net/minecraft/world/inventory/GrindstoneMenu.java b/net/minecraft/world/inventory/GrindstoneMenu.java -index 6eaa468c90a826f9fdecf2cf672c4893122d2504..b7ef712181c88bac7ccb505147013405cb05c6cb 100644 +index 18c15a7657e6fd994a8f17d0812c822d6adc8eab..00a0ce28632a7f515a94087c2752e8787212f0d9 100644 --- a/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/net/minecraft/world/inventory/GrindstoneMenu.java @@ -178,7 +178,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { @@ -61,3 +112,53 @@ index 6eaa468c90a826f9fdecf2cf672c4893122d2504..b7ef712181c88bac7ccb505147013405 return ItemStack.EMPTY; } +diff --git a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +index 4fdb3c36b39213f01f86ba281c7b62af99f5dcce..646d4c26870bb03f6d397b5e03ad97923d0928b2 100644 +--- a/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java +@@ -409,7 +409,11 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + ItemStack itemStack = this.items.get(index); + boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemStack, stack); + this.items.set(index, stack); +- stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util ++ // Leaves end - grindstone overstacking ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking || !org.leavesmc.leaves.util.ItemOverstackUtils.CurseEnchantedBook.isCursedEnchantedBook(itemStack)) { ++ stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util ++ } ++ // Leaves end - grindstone overstacking + if (index == 0 && !flag && this.level instanceof ServerLevel serverLevel) { + this.cookingTotalTime = getTotalCookTime(serverLevel, this, this.recipeType, this.cookSpeedMultiplier); // Paper - cook speed multiplier API + this.cookingTimer = 0; +diff --git a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +index 63d6a43dab067aa4c8fb67095c455130196eef9f..561acadcf81dc219d88e8ec8bdbd4f5f8fcbadc3 100644 +--- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +@@ -145,6 +145,12 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co + @Override + public void setItem(int slot, ItemStack stack) { + this.getItems().set(slot, stack); ++ // Leaves end - grindstone overstacking ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && org.leavesmc.leaves.util.ItemOverstackUtils.CurseEnchantedBook.isCursedEnchantedBook(stack)) { ++ this.setChanged(); ++ return; ++ } ++ // Leaves end - grindstone overstacking + stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util + this.setChanged(); + } +diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java +index 1a4326df24188918542349ba7c812578e78723ee..a900cde0d7e6ddd6faf961e7861c3cc499164d7a 100644 +--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java ++++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java +@@ -113,6 +113,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen + public void setItem(int index, ItemStack stack) { + this.unpackLootTable(null); + this.getItems().set(index, stack); ++ // Leaves end - grindstone overstacking ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && org.leavesmc.leaves.util.ItemOverstackUtils.CurseEnchantedBook.isCursedEnchantedBook(stack)) { ++ return; ++ } ++ // Leaves end - grindstone overstacking + stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - item over-stack util + } + diff --git a/leaves-server/minecraft-patches/features/0100-Configurable-MC-67.patch b/leaves-server/minecraft-patches/features/0100-Configurable-MC-67.patch index 38315fec..cbc7b490 100644 --- a/leaves-server/minecraft-patches/features/0100-Configurable-MC-67.patch +++ b/leaves-server/minecraft-patches/features/0100-Configurable-MC-67.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable MC-67 diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index c7b085ac004f6be4e10ae929d2fed47dd916e2c9..4d91f2eb00ab9ab5daaf559ae4ed04f99875092b 100644 +index 7039619c240a582be1ade95f495042134d6acf68..9302371893eab9d8b02716502cb0fd1019e00a98 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3974,6 +3974,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4194,6 +4194,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean canTeleport(Level fromLevel, Level toLevel) { diff --git a/leaves-server/minecraft-patches/features/0103-Can-disable-LivingEntity-aiStep-alive-check.patch b/leaves-server/minecraft-patches/features/0103-Can-disable-LivingEntity-aiStep-alive-check.patch index da22c50b..0a37fc0e 100644 --- a/leaves-server/minecraft-patches/features/0103-Can-disable-LivingEntity-aiStep-alive-check.patch +++ b/leaves-server/minecraft-patches/features/0103-Can-disable-LivingEntity-aiStep-alive-check.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Can disable LivingEntity aiStep alive check diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index ce624ed17bc5c9b5e13d280f8dda736581b21821..d2f5118ceeebf95496daabf7597655d6565ad116 100644 +index 305c099d32f1472a6e8909cdf2a53cec8a31afb5..0fca2df8899d285bd09e5a4ebcc09c05f222f13a 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3233,7 +3233,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3285,7 +3285,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin } } diff --git a/leaves-server/minecraft-patches/features/0104-Fix-FallingBlockEntity-Duplicate.patch b/leaves-server/minecraft-patches/features/0104-Fix-FallingBlockEntity-Duplicate.patch index b30eac46..94f4226f 100644 --- a/leaves-server/minecraft-patches/features/0104-Fix-FallingBlockEntity-Duplicate.patch +++ b/leaves-server/minecraft-patches/features/0104-Fix-FallingBlockEntity-Duplicate.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix FallingBlockEntity Duplicate diff --git a/net/minecraft/world/entity/item/FallingBlockEntity.java b/net/minecraft/world/entity/item/FallingBlockEntity.java -index 31edd0d45ac6c38887e4cebffe5a7cf377b47466..b6e188cf9f224a9c4b75339acd0306758bf0cb71 100644 +index 595dee03e3a7d98d703e48fb53d82d7f392a2b3d..0fd2c522a5fb038a8c002970af6feebd9dc9c436 100644 --- a/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -382,7 +382,7 @@ public class FallingBlockEntity extends Entity { +@@ -387,7 +387,7 @@ public class FallingBlockEntity extends Entity { ResourceKey resourceKey1 = this.level().dimension(); boolean flag = (resourceKey1 == Level.END || resourceKey == Level.END) && resourceKey1 != resourceKey; Entity entity = super.teleport(teleportTransition); diff --git a/leaves-server/minecraft-patches/features/0105-Old-Block-remove-behaviour.patch b/leaves-server/minecraft-patches/features/0105-Old-Block-remove-behaviour.patch index 9aab25ee..a8bcc63f 100644 --- a/leaves-server/minecraft-patches/features/0105-Old-Block-remove-behaviour.patch +++ b/leaves-server/minecraft-patches/features/0105-Old-Block-remove-behaviour.patch @@ -99,7 +99,7 @@ index 42ee3f32fe44c1f0680c994a69201f7bd7792673..19214c236bca4e454e3bbe7dc50e00b6 protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) { if (!movedByPiston && this.getSignalForState(state) > 0) { diff --git a/net/minecraft/world/level/block/BaseRailBlock.java b/net/minecraft/world/level/block/BaseRailBlock.java -index 4e13f5b233018d648f8ff83447624353fd62683b..8ecc438a518703aedd5aeed00727023ff26555c5 100644 +index 5f99e18244501ed2d85be77b71f48cc93058cdb7..6bf50d9c3921b15f40b4fba273abeb4c2e0f30b3 100644 --- a/net/minecraft/world/level/block/BaseRailBlock.java +++ b/net/minecraft/world/level/block/BaseRailBlock.java @@ -121,6 +121,23 @@ public abstract class BaseRailBlock extends Block implements SimpleWaterloggedBl @@ -388,7 +388,7 @@ index 56cf6528f0cd9b8528490d7cee9a1f0e54108ef9..955854e5b3a18b8f1441145554a97c54 protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) { Containers.updateNeighboursAfterDestroy(state, level, pos); diff --git a/net/minecraft/world/level/block/LecternBlock.java b/net/minecraft/world/level/block/LecternBlock.java -index 5a9b601b7bf7e80b04ebd8f5c8b7d121031132c7..ee666995db38374193414d24fa38260c855be622 100644 +index 5a9b601b7bf7e80b04ebd8f5c8b7d121031132c7..b714d3c7649384a8fdbe0a713e2193e241c80618 100644 --- a/net/minecraft/world/level/block/LecternBlock.java +++ b/net/minecraft/world/level/block/LecternBlock.java @@ -197,6 +197,36 @@ public class LecternBlock extends BaseEntityBlock { @@ -411,7 +411,7 @@ index 5a9b601b7bf7e80b04ebd8f5c8b7d121031132c7..ee666995db38374193414d24fa38260c + } + + private void popBook(BlockState state, Level level, BlockPos pos) { -+ if (level.getBlockEntity(pos, false) instanceof LecternBlockEntity lecternBlockEntity) { // CraftBukkit - don't validate, type may be changed already ++ if (level.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) { // CraftBukkit - don't validate, type may be changed already // Leaves - the method with validate arg already removed by paper... + Direction direction = state.getValue(FACING); + ItemStack itemStack = lecternBlockEntity.getBook().copy(); + if (itemStack.isEmpty()) return; // CraftBukkit - SPIGOT-5500 @@ -729,7 +729,7 @@ index 6c789e56f21f01252c21786cfeb48d88485b5636..e24a61a4e2dac0159d52f07c93ddf860 protected void affectNeighborsAfterRemoval(BlockState state, ServerLevel level, BlockPos pos, boolean movedByPiston) { BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite()); diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java -index bbb1abfbfe7afd7b631cf269c1e338697cd016d2..768e5c6f1c0ce7d4bec41c37668249e708ebb4bc 100644 +index be66f0f1cb1b0bcec8f9489a1fdd8777df1adb6b..67719dce9017a4c86a70b62fb660bddc636d5582 100644 --- a/net/minecraft/world/level/block/state/BlockBehaviour.java +++ b/net/minecraft/world/level/block/state/BlockBehaviour.java @@ -171,6 +171,15 @@ public abstract class BlockBehaviour implements FeatureElement { @@ -762,10 +762,10 @@ index bbb1abfbfe7afd7b631cf269c1e338697cd016d2..768e5c6f1c0ce7d4bec41c37668249e7 this.getBlock().affectNeighborsAfterRemoval(this.asState(), level, pos, movedByPiston); } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 845319dd3e355f739cce70b7df3172dd146601b1..d0ae0a73f2a635c008e2d60374d5b85a10216c96 100644 +index 2cdca2917ce6a4912b57594697bf5543801eb868..d0d78d35c87973629dcd83b22ac0435a7498fe00 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -394,20 +394,26 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -396,20 +396,26 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p boolean flag = !blockState.is(block); boolean flag1 = (flags & 64) != 0; boolean flag2 = (flags & 256) == 0; diff --git a/leaves-server/minecraft-patches/features/0106-Revert-raid-changes.patch b/leaves-server/minecraft-patches/features/0106-Revert-raid-changes.patch index b3698ec1..44713da5 100644 --- a/leaves-server/minecraft-patches/features/0106-Revert-raid-changes.patch +++ b/leaves-server/minecraft-patches/features/0106-Revert-raid-changes.patch @@ -21,7 +21,7 @@ index 80f17f33f670018240c854df589cf90cdeab6e70..4c6ce6a4a730033802651b0c0052fc46 if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) { serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier)); diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java -index 62a3a8d46e10e6f02e3f515bbce5d9ba1f6566b8..6a45e00490f0067d25010371f7c5fa40bbe7671c 100644 +index b3a29ce523fb5de71589c7c17598bba17622f988..b74ad31e5bcac5e557f18ccfb5c92d4d94a0ba6d 100644 --- a/net/minecraft/world/entity/raid/Raid.java +++ b/net/minecraft/world/entity/raid/Raid.java @@ -333,7 +333,20 @@ public class Raid { @@ -109,10 +109,10 @@ index 62a3a8d46e10e6f02e3f515bbce5d9ba1f6566b8..6a45e00490f0067d25010371f7c5fa40 return this.addWaveMob(level, wave, raider, true); } diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java -index 39a6a4579931d7edb7ab8c072d62cfc9b02791c8..23c0581ad4e3921f89070609ec7c01d8a5a9b2de 100644 +index 7b697f1dfe8131296ef55cd88a8b9d7cd884eb44..56995040e0bb23e55031cd1179faa770596e15a3 100644 --- a/net/minecraft/world/entity/raid/Raider.java +++ b/net/minecraft/world/entity/raid/Raider.java -@@ -127,6 +127,43 @@ public abstract class Raider extends PatrollingMonster { +@@ -128,6 +128,43 @@ public abstract class Raider extends PatrollingMonster { currentRaid.removeFromRaid(serverLevel, this, false); } diff --git a/leaves-server/minecraft-patches/features/0107-Allow-anvil-destroy-item-entities.patch b/leaves-server/minecraft-patches/features/0107-Allow-anvil-destroy-item-entities.patch index dcf72837..3c825524 100644 --- a/leaves-server/minecraft-patches/features/0107-Allow-anvil-destroy-item-entities.patch +++ b/leaves-server/minecraft-patches/features/0107-Allow-anvil-destroy-item-entities.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Allow anvil destroy item entities diff --git a/net/minecraft/world/entity/item/FallingBlockEntity.java b/net/minecraft/world/entity/item/FallingBlockEntity.java -index b6e188cf9f224a9c4b75339acd0306758bf0cb71..ff8cd3d52bf9f3d117abfd7022d7f2ac8525e46a 100644 +index 0fd2c522a5fb038a8c002970af6feebd9dc9c436..2d0d6ad8c37c3187fbf35e5c7ff9a509da59c648 100644 --- a/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -275,7 +275,7 @@ public class FallingBlockEntity extends Entity { +@@ -282,7 +282,7 @@ public class FallingBlockEntity extends Entity { if (ceil < 0) { return false; } else { diff --git a/leaves-server/minecraft-patches/features/0108-Configurable-collision-behavior.patch b/leaves-server/minecraft-patches/features/0108-Configurable-collision-behavior.patch deleted file mode 100644 index 66fdd2a6..00000000 --- a/leaves-server/minecraft-patches/features/0108-Configurable-collision-behavior.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fortern -Date: Thu, 24 Oct 2024 23:10:34 +0800 -Subject: [PATCH] Configurable collision behavior - - -diff --git a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -index a97a2a8492f3858e3b622d26768b4d819c9b47a7..7178f8477d5c3840225b21ec1fb6612e660b85d3 100644 ---- a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -+++ b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -@@ -101,6 +101,14 @@ public final class CollisionUtil { - (box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON; - } - -+ // Leaves start - Configurable collision behavior -+ public static boolean voxelShapeIntersectVanilla(final AABB box1, final AABB box2) { -+ return box1.minX < box2.maxX && box1.maxX > box2.minX && -+ box1.minY < box2.maxY && box1.maxY > box2.minY && -+ box1.minZ < box2.maxZ && box1.maxZ > box2.minZ; -+ } -+ // Leaves end - Configurable collision behavior -+ - // assume !isEmpty(target) && abs(source_move) >= COLLISION_EPSILON - public static double collideX(final AABB target, final AABB source, final double source_move) { - if ((source.minY - target.maxY) < -COLLISION_EPSILON && (source.maxY - target.minY) > COLLISION_EPSILON && -@@ -2014,7 +2022,9 @@ public final class CollisionUtil { - AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); - if (singleAABB != null) { - singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ); -- if (!voxelShapeIntersect(aabb, singleAABB)) { -+ // Leaves start - Configurable collision behavior -+ if (shouldSkip(aabb, blockCollision, singleAABB)) { -+ // Leaves end - Configurable collision behavior - continue; - } - -@@ -2067,6 +2077,17 @@ public final class CollisionUtil { - return ret; - } - -+ // Leaves start - Configurable collision behavior -+ private static boolean shouldSkip(net.minecraft.world.phys.AABB aabb, net.minecraft.world.phys.shapes.VoxelShape blockCollision, net.minecraft.world.phys.AABB singleAABB) { -+ boolean isBlockShape = blockCollision == net.minecraft.world.phys.shapes.Shapes.block(); -+ return switch (org.leavesmc.leaves.LeavesConfig.fix.collisionBehavior) { -+ case PAPER -> !voxelShapeIntersect(aabb, singleAABB); -+ case VANILLA -> !voxelShapeIntersectVanilla(aabb, singleAABB); -+ case BLOCK_SHAPE_VANILLA -> isBlockShape && !voxelShapeIntersectVanilla(aabb, singleAABB) || !isBlockShape && !voxelShapeIntersect(aabb, singleAABB); -+ }; -+ } -+ // Leaves end - Configurable collision behavior -+ - public static boolean getEntityHardCollisions(final Level world, final Entity entity, AABB aabb, - final List into, final int collisionFlags, final Predicate predicate) { - final boolean checkOnly = (collisionFlags & COLLISION_FLAG_CHECK_ONLY) != 0; diff --git a/leaves-server/minecraft-patches/features/0109-Disable-vault-blacklist.patch b/leaves-server/minecraft-patches/features/0108-Disable-vault-blacklist.patch similarity index 100% rename from leaves-server/minecraft-patches/features/0109-Disable-vault-blacklist.patch rename to leaves-server/minecraft-patches/features/0108-Disable-vault-blacklist.patch diff --git a/leaves-server/minecraft-patches/features/0110-Fix-EntityPortalExitEvent-logic.patch b/leaves-server/minecraft-patches/features/0109-Fix-EntityPortalExitEvent-logic.patch similarity index 55% rename from leaves-server/minecraft-patches/features/0110-Fix-EntityPortalExitEvent-logic.patch rename to leaves-server/minecraft-patches/features/0109-Fix-EntityPortalExitEvent-logic.patch index 18df2652..65f3f753 100644 --- a/leaves-server/minecraft-patches/features/0110-Fix-EntityPortalExitEvent-logic.patch +++ b/leaves-server/minecraft-patches/features/0109-Fix-EntityPortalExitEvent-logic.patch @@ -5,37 +5,33 @@ Subject: [PATCH] Fix EntityPortalExitEvent logic diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 4d91f2eb00ab9ab5daaf559ae4ed04f99875092b..b478a1fedeeee2c19bddc66e2ae4152b4d72c724 100644 +index 9302371893eab9d8b02716502cb0fd1019e00a98..61765061064cff706280b25dbbfbd160fc6c3966 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -3778,19 +3778,29 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - if (this.portalProcess != null) { // if in a portal - org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity = this.getBukkitEntity(); -+ org.bukkit.util.Vector after = org.bukkit.craftbukkit.util.CraftVector.toBukkit(velocity); // Leaves - fix - org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent( - bukkitEntity, - bukkitEntity.getLocation(), to.clone(), -- bukkitEntity.getVelocity(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(velocity) -+ bukkitEntity.getVelocity(), after // Leaves - fix +@@ -3984,19 +3984,21 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess ); event.callEvent(); + // Leaves start - fix // Only change the target if actually needed, since we reset relative flags -- if (!event.isCancelled() && event.getTo() != null && (!event.getTo().equals(event.getFrom()) || !event.getAfter().equals(event.getBefore()))) { // todo this looks broken -- to = event.getTo().clone(); -- velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getAfter()); +- if (event.isCancelled() || !to.equals(event.getTo()) || !after.equals(event.getAfter())) { +- if (event.isCancelled() || event.getTo() == null) { +- org.bukkit.World toWorld = to.getWorld(); +- to = event.getFrom().clone(); +- to.setWorld(toWorld); // cancelling doesn't cancel the teleport just the position/velocity (old quirk) +- velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getBefore()); +- } else { +- to = event.getTo().clone(); + if (event.isCancelled() || (!to.equals(event.getTo()) || !after.equals(event.getAfter()))) { + if (!event.isCancelled()) { + if (event.getTo() != null) { + to = event.getTo().clone(); + } -+ velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getAfter()); + velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getAfter()); + } else { + to = event.getFrom().clone(); + velocity = Vec3.ZERO; -+ } + } teleportTransition = new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3(to), velocity, to.getYaw(), to.getPitch(), teleportTransition.missingRespawnBlock(), teleportTransition.asPassenger(), Set.of(), teleportTransition.postTeleportTransition(), teleportTransition.cause()); } + // Leaves end - fix diff --git a/leaves-server/minecraft-patches/features/0111-Fix-CraftPortalEvent-logic.patch b/leaves-server/minecraft-patches/features/0110-Fix-CraftPortalEvent-logic.patch similarity index 90% rename from leaves-server/minecraft-patches/features/0111-Fix-CraftPortalEvent-logic.patch rename to leaves-server/minecraft-patches/features/0110-Fix-CraftPortalEvent-logic.patch index cca040dc..2bb5b241 100644 --- a/leaves-server/minecraft-patches/features/0111-Fix-CraftPortalEvent-logic.patch +++ b/leaves-server/minecraft-patches/features/0110-Fix-CraftPortalEvent-logic.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix CraftPortalEvent logic diff --git a/net/minecraft/world/level/block/EndPortalBlock.java b/net/minecraft/world/level/block/EndPortalBlock.java -index cf2b105c98a3b22b9bea59cbafcd598657dc92b5..22ffa5743f95d28f29084f1dd357015aee032711 100644 +index f6c64277c3d6e16250e2bf963b6427404e27aa9b..2d908255439ea548aa7679219b5092334243a641 100644 --- a/net/minecraft/world/level/block/EndPortalBlock.java +++ b/net/minecraft/world/level/block/EndPortalBlock.java -@@ -103,9 +103,9 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { +@@ -105,9 +105,9 @@ public class EndPortalBlock extends BaseEntityBlock implements Portal { } // CraftBukkit start diff --git a/leaves-server/minecraft-patches/features/0112-Xaero-Map-Protocol.patch b/leaves-server/minecraft-patches/features/0111-Xaero-Map-Protocol.patch similarity index 87% rename from leaves-server/minecraft-patches/features/0112-Xaero-Map-Protocol.patch rename to leaves-server/minecraft-patches/features/0111-Xaero-Map-Protocol.patch index 4400addf..d002e9af 100644 --- a/leaves-server/minecraft-patches/features/0112-Xaero-Map-Protocol.patch +++ b/leaves-server/minecraft-patches/features/0111-Xaero-Map-Protocol.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Xaero Map Protocol diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index df58e2cd1a8be7c4b24a747ca40d0e79bf40f976..f6c2f02e1a7f5ac2d7bb584893457761fe30b509 100644 +index 1d370d5fc9f69bcf2f7087373e9b53fbac792821..37999b937a88c8fd9ca2cba24dc6383e09610eb5 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -1343,6 +1343,7 @@ public abstract class PlayerList { +@@ -1319,6 +1319,7 @@ public abstract class PlayerList { player.connection.send(new ClientboundInitializeBorderPacket(worldBorder)); player.connection.send(new ClientboundSetTimePacket(level.getGameTime(), level.getDayTime(), level.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle())); diff --git a/leaves-server/minecraft-patches/features/0113-Skip-negligible-planar-movement-multiplication.patch b/leaves-server/minecraft-patches/features/0112-Skip-negligible-planar-movement-multiplication.patch similarity index 91% rename from leaves-server/minecraft-patches/features/0113-Skip-negligible-planar-movement-multiplication.patch rename to leaves-server/minecraft-patches/features/0112-Skip-negligible-planar-movement-multiplication.patch index fae0c2bd..127a522b 100644 --- a/leaves-server/minecraft-patches/features/0113-Skip-negligible-planar-movement-multiplication.patch +++ b/leaves-server/minecraft-patches/features/0112-Skip-negligible-planar-movement-multiplication.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Skip negligible planar movement multiplication This patch is Powered by Gale(https://github.com/Dreeam-qwq/Gale) diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 91038b21164d3e1bf6406117478454d38b24bb81..d768b1de1bc75ab73198379b1099cc09f58d1ca4 100644 +index d158471bd95f3e4f810ba41ea07ee6b4d341d42f..47b9ddcecd0853927a4a41264bda15a935b55671 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -1218,8 +1218,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1234,8 +1234,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } diff --git a/leaves-server/minecraft-patches/features/0114-Skippable-raid-height-check.patch b/leaves-server/minecraft-patches/features/0113-Skippable-raid-height-check.patch similarity index 92% rename from leaves-server/minecraft-patches/features/0114-Skippable-raid-height-check.patch rename to leaves-server/minecraft-patches/features/0113-Skippable-raid-height-check.patch index f344d36b..2c0f3dcc 100644 --- a/leaves-server/minecraft-patches/features/0114-Skippable-raid-height-check.patch +++ b/leaves-server/minecraft-patches/features/0113-Skippable-raid-height-check.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Skippable raid height check diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java -index 6a45e00490f0067d25010371f7c5fa40bbe7671c..8e08a187da6f40d1b3bc990401af36e510537777 100644 +index b74ad31e5bcac5e557f18ccfb5c92d4d94a0ba6d..14cbc32c1ebb1eb777c9ae45ff5b2178b469dea2 100644 --- a/net/minecraft/world/entity/raid/Raid.java +++ b/net/minecraft/world/entity/raid/Raid.java @@ -687,7 +687,7 @@ public class Raid { diff --git a/leaves-server/minecraft-patches/features/0115-Support-REI-protocol.patch b/leaves-server/minecraft-patches/features/0114-Support-REI-protocol.patch similarity index 100% rename from leaves-server/minecraft-patches/features/0115-Support-REI-protocol.patch rename to leaves-server/minecraft-patches/features/0114-Support-REI-protocol.patch diff --git a/leaves-server/minecraft-patches/features/0116-Vanilla-player-display-name.patch b/leaves-server/minecraft-patches/features/0115-Vanilla-player-display-name.patch similarity index 82% rename from leaves-server/minecraft-patches/features/0116-Vanilla-player-display-name.patch rename to leaves-server/minecraft-patches/features/0115-Vanilla-player-display-name.patch index 3e7f52c6..2e5c4846 100644 --- a/leaves-server/minecraft-patches/features/0116-Vanilla-player-display-name.patch +++ b/leaves-server/minecraft-patches/features/0115-Vanilla-player-display-name.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Vanilla player display name diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index f144a8bd5eb55ce093ad92ffd1304860dc52c1b1..fa93076169e19c7d2d1134dea297968a650dc220 100644 +index 5e74fdf09d5063b955d9c5ed63775b38f562687e..d92c018de29cc377cc8e7188fc2d316e96b1f369 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -471,7 +471,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc - +@@ -476,7 +476,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc + this.object = null; // CraftBukkit start this.displayName = this.getScoreboardName(); - this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper + this.adventure$displayName = org.leavesmc.leaves.LeavesConfig.fix.vanillaDisplayName ? io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getDisplayName()) : net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper // Leaves - Vanilla display name this.bukkitPickUpLoot = true; this.maxHealthCache = this.getMaxHealth(); - } + // CraftBukkit end diff --git a/leaves-server/minecraft-patches/features/0117-Fix-SculkCatalyst-exp-skip.patch b/leaves-server/minecraft-patches/features/0116-Fix-SculkCatalyst-exp-skip.patch similarity index 80% rename from leaves-server/minecraft-patches/features/0117-Fix-SculkCatalyst-exp-skip.patch rename to leaves-server/minecraft-patches/features/0116-Fix-SculkCatalyst-exp-skip.patch index 62c07c2c..b0b32f0b 100644 --- a/leaves-server/minecraft-patches/features/0117-Fix-SculkCatalyst-exp-skip.patch +++ b/leaves-server/minecraft-patches/features/0116-Fix-SculkCatalyst-exp-skip.patch @@ -5,19 +5,19 @@ Subject: [PATCH] Fix SculkCatalyst exp skip diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 8c7fce6d97a4a526c06bba8bb20d1e64d3d94e92..b2bb4a2c1ba2e924f380f69365ce7384db21eed6 100644 +index d92c018de29cc377cc8e7188fc2d316e96b1f369..cd7dd412ab714fe0dc3f180a2dee1b3547292a81 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1091,7 +1091,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1101,7 +1101,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc } // SPIGOT-5478 must be called manually now -- if (event.shouldDropExperience()) this.dropExperience(this.serverLevel(), cause.getEntity()); // Paper - tie to event -+ if (shouldDropExperience(event.shouldDropExperience(), event.forceUseEventDropStatus())) this.dropExperience(this.serverLevel(), cause.getEntity()); // Paper - tie to event // Leaves - exp fix +- if (event.shouldDropExperience()) this.dropExperience(this.level(), cause.getEntity()); // Paper - tie to event ++ if (shouldDropExperience(event.shouldDropExperience(), event.forceUseEventDropStatus())) this.dropExperience(this.level(), cause.getEntity()); // Paper - tie to event // Leaves - exp fix // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. if (!event.getKeepInventory()) { // Paper start - PlayerDeathEvent#getItemsToKeep -@@ -1138,6 +1138,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1148,6 +1148,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc this.setClientLoaded(false); } @@ -34,18 +34,18 @@ index 8c7fce6d97a4a526c06bba8bb20d1e64d3d94e92..b2bb4a2c1ba2e924f380f69365ce7384 AABB aabb = new AABB(this.blockPosition()).inflate(32.0, 10.0, 32.0); this.level() diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index d2f5118ceeebf95496daabf7597655d6565ad116..8975acf713dd806693e3b3045c98e53321a2e5f4 100644 +index 0fca2df8899d285bd09e5a4ebcc09c05f222f13a..b33c78f836830dd47e275cab9c9f87531152a96b 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -264,6 +264,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - protected final EntityEquipment equipment; +@@ -277,6 +277,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + private Waypoint.Icon locatorBarIcon = new Waypoint.Icon(); // CraftBukkit start public int expToDrop; + public int expToReward; // Leaves - exp fix public List drops = new java.util.ArrayList<>(); // Paper - Restore vanilla drops behavior public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; public boolean collides = true; -@@ -1829,6 +1830,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1861,6 +1862,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin entity.killedEntity((ServerLevel) this.level(), this); } this.gameEvent(GameEvent.ENTITY_DIE); @@ -53,7 +53,7 @@ index d2f5118ceeebf95496daabf7597655d6565ad116..8975acf713dd806693e3b3045c98e533 } else { this.dead = false; this.setHealth((float) deathEvent.getReviveHealth()); -@@ -1902,7 +1904,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1934,7 +1936,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin this.drops = new java.util.ArrayList<>(); // this.dropEquipment(level); // CraftBukkit - moved up // CraftBukkit end @@ -63,7 +63,7 @@ index d2f5118ceeebf95496daabf7597655d6565ad116..8975acf713dd806693e3b3045c98e533 } diff --git a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java -index 2627583ab12d886b1fba0b1d1e599f942926b499..be09fa81ed1e58a271156299dacf49be649eecfc 100644 +index 0a94670dc20bb9c521b0395633eb100393895f6a..a2f73e8210ac554a7529067bbe9f50267f2bf0e2 100644 --- a/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SculkCatalystBlockEntity.java @@ -96,8 +96,7 @@ public class SculkCatalystBlockEntity extends BlockEntity implements GameEventLi diff --git a/leaves-server/minecraft-patches/features/0118-Vanilla-creative-pickup-behavior.patch b/leaves-server/minecraft-patches/features/0117-Vanilla-creative-pickup-behavior.patch similarity index 85% rename from leaves-server/minecraft-patches/features/0118-Vanilla-creative-pickup-behavior.patch rename to leaves-server/minecraft-patches/features/0117-Vanilla-creative-pickup-behavior.patch index dfef9d82..60818f62 100644 --- a/leaves-server/minecraft-patches/features/0118-Vanilla-creative-pickup-behavior.patch +++ b/leaves-server/minecraft-patches/features/0117-Vanilla-creative-pickup-behavior.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Vanilla creative pickup behavior diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java -index 57bf2819271b3293a065b58d31b609f8463811b4..1d61b01d32783357ea5d766cb716ba4c7edb1407 100644 +index 71df58ae26325a2d28b6679733c474c0c59f7654..c73a1289a122dd0525e93fafb522d774566dceac 100644 --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -159,6 +159,13 @@ public class Inventory implements Container, Nameable { +@@ -176,6 +176,13 @@ public class Inventory implements Container, Nameable { // CraftBukkit start - Watch method above! :D public int canHold(ItemStack itemStack) { int remains = itemStack.getCount(); diff --git a/leaves-server/minecraft-patches/features/0119-Vanilla-portal-handle.patch b/leaves-server/minecraft-patches/features/0118-Vanilla-portal-handle.patch similarity index 84% rename from leaves-server/minecraft-patches/features/0119-Vanilla-portal-handle.patch rename to leaves-server/minecraft-patches/features/0118-Vanilla-portal-handle.patch index 76da4617..206c86c9 100644 --- a/leaves-server/minecraft-patches/features/0119-Vanilla-portal-handle.patch +++ b/leaves-server/minecraft-patches/features/0118-Vanilla-portal-handle.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Vanilla portal handle diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index d768b1de1bc75ab73198379b1099cc09f58d1ca4..0ec5603097a984713bc3ae7a03a7535e552cf851 100644 +index 47b9ddcecd0853927a4a41264bda15a935b55671..0dde70f12ede6da06a0b9f0e78272a963a167699 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -807,6 +807,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -836,6 +836,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // CraftBukkit start public void postTick() { @@ -16,7 +16,7 @@ index d768b1de1bc75ab73198379b1099cc09f58d1ca4..0ec5603097a984713bc3ae7a03a7535e // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities this.handlePortal(); -@@ -827,7 +828,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -856,7 +857,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.boardingCooldown--; } @@ -26,10 +26,10 @@ index d768b1de1bc75ab73198379b1099cc09f58d1ca4..0ec5603097a984713bc3ae7a03a7535e this.spawnSprintParticle(); } diff --git a/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/net/minecraft/world/entity/vehicle/AbstractMinecart.java -index 99617c08cbd989092ba357d8df928786fd04c89a..619f87b4ce69629b230229f33487fc653f6a39a7 100644 +index 7e61d68b36ca2768f70dc1fc130a8d7b95347b6b..8e73204f6e7d159d66c3d90c7e2845bfde867e7a 100644 --- a/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -294,7 +294,7 @@ public abstract class AbstractMinecart extends VehicleEntity { +@@ -293,7 +293,7 @@ public abstract class AbstractMinecart extends VehicleEntity { } this.checkBelowWorld(); diff --git a/leaves-server/minecraft-patches/features/0120-Fix-chunk-reload-detector.patch b/leaves-server/minecraft-patches/features/0119-Fix-chunk-reload-detector.patch similarity index 87% rename from leaves-server/minecraft-patches/features/0120-Fix-chunk-reload-detector.patch rename to leaves-server/minecraft-patches/features/0119-Fix-chunk-reload-detector.patch index 713f4f29..ca114a73 100644 --- a/leaves-server/minecraft-patches/features/0120-Fix-chunk-reload-detector.patch +++ b/leaves-server/minecraft-patches/features/0119-Fix-chunk-reload-detector.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix chunk reload detector diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index 7681195587d361acf524d09ad3958e628aad73b6..edf9c01fd64d269a5d78d805db91177095edffc7 100644 +index f6b2d541fdfd11c6ff6033fbf4cd5153796634e3..5e06cc272b9617d780c507b5b819b380e7462eaf 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java -@@ -396,7 +396,7 @@ public class ServerEntity { +@@ -390,7 +390,7 @@ public class ServerEntity { if (!list.isEmpty()) { consumer.accept(new ClientboundSetEquipmentPacket(this.entity.getId(), list, true)); // Paper - data sanitization } diff --git a/leaves-server/minecraft-patches/features/0121-Do-not-reset-placed-block-on-exception.patch b/leaves-server/minecraft-patches/features/0120-Do-not-reset-placed-block-on-exception.patch similarity index 96% rename from leaves-server/minecraft-patches/features/0121-Do-not-reset-placed-block-on-exception.patch rename to leaves-server/minecraft-patches/features/0120-Do-not-reset-placed-block-on-exception.patch index 6610df3b..4bd2ee6d 100644 --- a/leaves-server/minecraft-patches/features/0121-Do-not-reset-placed-block-on-exception.patch +++ b/leaves-server/minecraft-patches/features/0120-Do-not-reset-placed-block-on-exception.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Do not reset placed block on exception diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java -index 5cbd5d04de525c33715bc45826bd2ed446355505..c320cd4b7d994b3a0d23bec1713a8bf910f4ef95 100644 +index 17e35aa9efc55a52ad64f05e8fdc3c7fae3ef0c4..699a0fe62204f0f4b9677ec1e0d894b918b7aef9 100644 --- a/net/minecraft/world/item/BlockItem.java +++ b/net/minecraft/world/item/BlockItem.java @@ -92,20 +92,22 @@ public class BlockItem extends Item { diff --git a/leaves-server/minecraft-patches/features/0122-Do-not-prevent-block-entity-and-entity-crash-at-Leve.patch b/leaves-server/minecraft-patches/features/0121-Do-not-prevent-block-entity-and-entity-crash-at-Leve.patch similarity index 93% rename from leaves-server/minecraft-patches/features/0122-Do-not-prevent-block-entity-and-entity-crash-at-Leve.patch rename to leaves-server/minecraft-patches/features/0121-Do-not-prevent-block-entity-and-entity-crash-at-Leve.patch index 4bf7a462..bb5f210f 100644 --- a/leaves-server/minecraft-patches/features/0122-Do-not-prevent-block-entity-and-entity-crash-at-Leve.patch +++ b/leaves-server/minecraft-patches/features/0121-Do-not-prevent-block-entity-and-entity-crash-at-Leve.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Do not prevent block entity and entity crash at LevelChunk diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index d0ae0a73f2a635c008e2d60374d5b85a10216c96..90888df3fb4ee72c02815322b4b1d643c1d1420e 100644 +index d0d78d35c87973629dcd83b22ac0435a7498fe00..56e7df059cd070a8f472d6712dfb08d14ffa8819 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -945,12 +945,14 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -952,12 +952,14 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p profilerFiller.pop(); } catch (Throwable var5) { diff --git a/leaves-server/minecraft-patches/features/0123-Tripwire-behavior-modifier.patch b/leaves-server/minecraft-patches/features/0122-Tripwire-behavior-modifier.patch similarity index 100% rename from leaves-server/minecraft-patches/features/0123-Tripwire-behavior-modifier.patch rename to leaves-server/minecraft-patches/features/0122-Tripwire-behavior-modifier.patch diff --git a/leaves-server/minecraft-patches/features/0124-Old-nether-portal-collision.patch b/leaves-server/minecraft-patches/features/0123-Old-nether-portal-collision.patch similarity index 59% rename from leaves-server/minecraft-patches/features/0124-Old-nether-portal-collision.patch rename to leaves-server/minecraft-patches/features/0123-Old-nether-portal-collision.patch index 72e8d499..5eb752b8 100644 --- a/leaves-server/minecraft-patches/features/0124-Old-nether-portal-collision.patch +++ b/leaves-server/minecraft-patches/features/0123-Old-nether-portal-collision.patch @@ -6,15 +6,15 @@ Subject: [PATCH] Old nether portal collision It will be removed in 1.21.6 mojang revert it again. diff --git a/net/minecraft/world/level/block/NetherPortalBlock.java b/net/minecraft/world/level/block/NetherPortalBlock.java -index 171b383efabbbe849aff28832c47076f85a46307..173e97c27e9373a41d33cda6a877b17a38f516a1 100644 +index 3aabae6e27e692aa65cc931e57306426e0f4d645..76dc4eb719244f002e327919c6b8aac8b359b5f0 100644 --- a/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -65,7 +65,7 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -60,7 +60,7 @@ public class NetherPortalBlock extends Block implements Portal { @Override - protected VoxelShape getEntityInsideCollisionShape(BlockState state, BlockGetter level, BlockPos pos, Entity entity) { -- return state.getShape(level, pos); -+ return org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldNetherPortalCollision ? Shapes.block() : state.getShape(level, pos); // Leaves - Old nether portal collision + protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) { +- return SHAPES.get(state.getValue(AXIS)); ++ return org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldNetherPortalCollision ? Shapes.block() : SHAPES.get(state.getValue(AXIS)); // Leaves - Old nether portal collision } @Override diff --git a/leaves-server/minecraft-patches/features/0125-Spawn-invulnerable-time.patch b/leaves-server/minecraft-patches/features/0124-Spawn-invulnerable-time.patch similarity index 87% rename from leaves-server/minecraft-patches/features/0125-Spawn-invulnerable-time.patch rename to leaves-server/minecraft-patches/features/0124-Spawn-invulnerable-time.patch index a00bd132..0cc80c89 100644 --- a/leaves-server/minecraft-patches/features/0125-Spawn-invulnerable-time.patch +++ b/leaves-server/minecraft-patches/features/0124-Spawn-invulnerable-time.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Spawn invulnerable time diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index b2bb4a2c1ba2e924f380f69365ce7384db21eed6..2521f6aff4479710ab10c7df5031f6af273fce64 100644 +index cd7dd412ab714fe0dc3f180a2dee1b3547292a81..18de3e99b83a7e2ecf018456ee51361b06d6451b 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -221,6 +221,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -232,6 +232,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc private int lastSentFood = -99999999; private boolean lastFoodSaturationZero = true; public int lastSentExp = -99999999; @@ -16,7 +16,7 @@ index b2bb4a2c1ba2e924f380f69365ce7384db21eed6..2521f6aff4479710ab10c7df5031f6af private ChatVisiblity chatVisibility = ChatVisiblity.FULL; public ParticleStatus particleStatus = ParticleStatus.ALL; private boolean canChatColor = true; -@@ -751,6 +752,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -752,6 +753,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc this.resetOperationCountPerTick(); // Leaves - player operation limiter this.gameMode.tick(); this.wardenSpawnTracker.tick(); @@ -24,7 +24,7 @@ index b2bb4a2c1ba2e924f380f69365ce7384db21eed6..2521f6aff4479710ab10c7df5031f6af if (this.invulnerableTime > 0) { this.invulnerableTime--; } -@@ -1189,6 +1191,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -1199,6 +1201,13 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc if (this.isInvulnerableTo(level, damageSource)) { return false; } else { diff --git a/leaves-server/minecraft-patches/features/0126-Old-zombie-reinforcement.patch b/leaves-server/minecraft-patches/features/0125-Old-zombie-reinforcement.patch similarity index 86% rename from leaves-server/minecraft-patches/features/0126-Old-zombie-reinforcement.patch rename to leaves-server/minecraft-patches/features/0125-Old-zombie-reinforcement.patch index 4a82f5f7..636942dd 100644 --- a/leaves-server/minecraft-patches/features/0126-Old-zombie-reinforcement.patch +++ b/leaves-server/minecraft-patches/features/0125-Old-zombie-reinforcement.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Old zombie reinforcement diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java -index 39b65970a48568c95ff482b9636e7391f300ffa8..50417ae5883374113cf820c064570b6aeda4fbb8 100644 +index a23607874a72723914cbfeea0ad1c51236c044d8..cb7b248276bfb6a9721e0bcc42ef00bf7029f263 100644 --- a/net/minecraft/world/entity/monster/Zombie.java +++ b/net/minecraft/world/entity/monster/Zombie.java -@@ -342,7 +342,7 @@ public class Zombie extends Monster { +@@ -341,7 +341,7 @@ public class Zombie extends Monster { int floor = Mth.floor(this.getX()); int floor1 = Mth.floor(this.getY()); int floor2 = Mth.floor(this.getZ()); diff --git a/leaves-server/minecraft-patches/features/0127-Sound-update-suppression.patch b/leaves-server/minecraft-patches/features/0126-Sound-update-suppression.patch similarity index 94% rename from leaves-server/minecraft-patches/features/0127-Sound-update-suppression.patch rename to leaves-server/minecraft-patches/features/0126-Sound-update-suppression.patch index 3f407e7d..89776e10 100644 --- a/leaves-server/minecraft-patches/features/0127-Sound-update-suppression.patch +++ b/leaves-server/minecraft-patches/features/0126-Sound-update-suppression.patch @@ -32,10 +32,10 @@ index fa9cb4c40a41eea7fd63a4513d0b0f39067de9ba..331276f4464d78dc86f35fe7d9c42864 return state.getBlock() instanceof SculkSensorBlock && getPhase(state) == SculkSensorPhase.INACTIVE; // Paper - Check for a valid type } diff --git a/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java b/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java -index 26d2205fe7c1322f52e7d162e1be9dc23349f3b6..9cbba9cdeddd0a722554aca0a1fb41c2def4a46b 100644 +index 9a345fa3438b2d17a5de2fa0c0b0daef5a5183e1..f3f92666265e1b6dcb17124b5f52e84a6d62ccf2 100644 --- a/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java -@@ -118,7 +118,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList +@@ -113,7 +113,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList public boolean canReceiveVibration(ServerLevel level, BlockPos pos, Holder gameEvent, @Nullable GameEvent.Context context) { return (!pos.equals(this.blockPos) || !gameEvent.is(GameEvent.BLOCK_DESTROY) && !gameEvent.is(GameEvent.BLOCK_PLACE)) && VibrationSystem.getGameEventFrequency(gameEvent) != 0 @@ -44,7 +44,7 @@ index 26d2205fe7c1322f52e7d162e1be9dc23349f3b6..9cbba9cdeddd0a722554aca0a1fb41c2 } @Override -@@ -126,7 +126,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList +@@ -121,7 +121,7 @@ public class SculkSensorBlockEntity extends BlockEntity implements GameEventList ServerLevel level, BlockPos pos, Holder gameEvent, @Nullable Entity entity, @Nullable Entity playerEntity, float distance ) { BlockState blockState = SculkSensorBlockEntity.this.getBlockState(); diff --git a/leaves-server/minecraft-patches/features/0128-Old-zombie-piglin-drop-behavior.patch b/leaves-server/minecraft-patches/features/0127-Old-zombie-piglin-drop-behavior.patch similarity index 54% rename from leaves-server/minecraft-patches/features/0128-Old-zombie-piglin-drop-behavior.patch rename to leaves-server/minecraft-patches/features/0127-Old-zombie-piglin-drop-behavior.patch index b9eefe24..a6883d7e 100644 --- a/leaves-server/minecraft-patches/features/0128-Old-zombie-piglin-drop-behavior.patch +++ b/leaves-server/minecraft-patches/features/0127-Old-zombie-piglin-drop-behavior.patch @@ -5,17 +5,16 @@ Subject: [PATCH] Old zombie piglin drop behavior diff --git a/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/net/minecraft/world/entity/monster/ZombifiedPiglin.java -index 05de183ce7b0be9b41f005b2ca36807a109fc634..6c3895f96ef0c3bd69dc5cd0fae56c83116537a3 100644 +index 822712eaff2f6c579d982734ab14a00c02182770..abc18460374a246d0895dd56a3c3d8a6503ccde4 100644 --- a/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/net/minecraft/world/entity/monster/ZombifiedPiglin.java -@@ -159,6 +159,10 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { - this.ticksUntilNextAlert = ALERT_INTERVAL.sample(this.random); +@@ -113,6 +113,9 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { + this.maybeAlertOthers(); } -+ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldZombiePiglinDrop && livingEntity instanceof Player player) { -+ this.setLastHurtByPlayer(player, super.tickCount); -+ } + - return super.setTarget(livingEntity, reason); // CraftBukkit ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldZombiePiglinDrop && this.isAngry()) this.lastHurtByPlayerMemoryTime = this.tickCount; // Leaves - old zombie piglin drop ++ + super.customServerAiStep(level); } diff --git a/leaves-server/minecraft-patches/features/0129-Fast-exp-orb-absorb.patch b/leaves-server/minecraft-patches/features/0128-Fast-exp-orb-absorb.patch similarity index 93% rename from leaves-server/minecraft-patches/features/0129-Fast-exp-orb-absorb.patch rename to leaves-server/minecraft-patches/features/0128-Fast-exp-orb-absorb.patch index 58f5e9bd..377e34c3 100644 --- a/leaves-server/minecraft-patches/features/0129-Fast-exp-orb-absorb.patch +++ b/leaves-server/minecraft-patches/features/0128-Fast-exp-orb-absorb.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fast exp orb absorb diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java -index c97a0e500e889b406cb2d679a3870715775f5393..9ebc2fdf9de21bb4533e4184ec9fb92b698902bd 100644 +index a62edee768c30c99213baa6bd736d67ae52b558c..82fb285f53513cc62f8f7b78b85a91076c73545a 100644 --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -328,6 +328,20 @@ public class ExperienceOrb extends Entity { +@@ -358,6 +358,20 @@ public class ExperienceOrb extends Entity { public void playerTouch(Player entity) { if (entity instanceof ServerPlayer serverPlayer) { if (entity.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent diff --git a/leaves-server/minecraft-patches/features/0129-Vanilla-Fluid-Pushing.patch b/leaves-server/minecraft-patches/features/0129-Vanilla-Fluid-Pushing.patch new file mode 100644 index 00000000..f1794616 --- /dev/null +++ b/leaves-server/minecraft-patches/features/0129-Vanilla-Fluid-Pushing.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Fortern +Date: Thu, 19 Jun 2025 00:49:24 +0800 +Subject: [PATCH] Vanilla Fluid Pushing + + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 34e71d35a28954d9cb13a349de09f1303cdd11b8..096aee98257f24ce187682c256d80b0b13611339 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -4729,8 +4729,82 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return Mth.lerp(partialTick, this.yRotO, this.yRot); + } + ++ // Leaves start - vanilla fluid pushing ++ private boolean vanillaUpdateFluidHeightAndDoFluidPushing(final TagKey fluidTag, final double motionScale) { ++ if (this.touchingUnloadedChunk()) { ++ return false; ++ } else { ++ AABB aabb = this.getBoundingBox().deflate(0.001); ++ int floor = Mth.floor(aabb.minX); ++ int ceil = Mth.ceil(aabb.maxX); ++ int floor1 = Mth.floor(aabb.minY); ++ int ceil1 = Mth.ceil(aabb.maxY); ++ int floor2 = Mth.floor(aabb.minZ); ++ int ceil2 = Mth.ceil(aabb.maxZ); ++ double d = 0.0; ++ boolean isPushedByFluid = this.isPushedByFluid(); ++ boolean flag = false; ++ Vec3 vec3 = Vec3.ZERO; ++ int i = 0; ++ BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); ++ ++ for (int i1 = floor; i1 < ceil; i1++) { ++ for (int i2 = floor1; i2 < ceil1; i2++) { ++ for (int i3 = floor2; i3 < ceil2; i3++) { ++ mutableBlockPos.set(i1, i2, i3); ++ FluidState fluidState = this.level().getFluidState(mutableBlockPos); ++ if (fluidState.is(fluidTag)) { ++ double d1 = i2 + fluidState.getHeight(this.level(), mutableBlockPos); ++ if (d1 >= aabb.minY) { ++ flag = true; ++ d = Math.max(d1 - aabb.minY, d); ++ if (isPushedByFluid) { ++ Vec3 flow = fluidState.getFlow(this.level(), mutableBlockPos); ++ if (d < 0.4) { ++ flow = flow.scale(d); ++ } ++ ++ vec3 = vec3.add(flow); ++ i++; ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ if (vec3.length() > 0.0) { ++ if (i > 0) { ++ vec3 = vec3.scale(1.0 / i); ++ } ++ ++ if (!(this instanceof Player)) { ++ vec3 = vec3.normalize(); ++ } ++ ++ Vec3 deltaMovement = this.getDeltaMovement(); ++ vec3 = vec3.scale(motionScale); ++ double d2 = 0.003; ++ if (Math.abs(deltaMovement.x) < 0.003 && Math.abs(deltaMovement.z) < 0.003 && vec3.length() < 0.0045000000000000005) { ++ vec3 = vec3.normalize().scale(0.0045000000000000005); ++ } ++ ++ this.setDeltaMovement(this.getDeltaMovement().add(vec3)); ++ } ++ ++ this.fluidHeight.put(fluidTag, d); ++ return flag; ++ } ++ } ++ // Leaves end - vanilla fluid pushing ++ + // Paper start - optimise collisions + public boolean updateFluidHeightAndDoFluidPushing(final TagKey fluid, final double flowScale) { ++ // Leaves start - vanilla fluid pushing ++ if (org.leavesmc.leaves.LeavesConfig.fix.vanillaFluidPushing) { ++ return vanillaUpdateFluidHeightAndDoFluidPushing(fluid, flowScale); ++ } ++ // Leaves end - vanilla fluid pushing + if (this.touchingUnloadedChunk()) { + return false; + } diff --git a/leaves-server/minecraft-patches/features/0131-Configurable-item-damage-check.patch b/leaves-server/minecraft-patches/features/0130-Configurable-item-damage-check.patch similarity index 88% rename from leaves-server/minecraft-patches/features/0131-Configurable-item-damage-check.patch rename to leaves-server/minecraft-patches/features/0130-Configurable-item-damage-check.patch index eac44ad4..9d074978 100644 --- a/leaves-server/minecraft-patches/features/0131-Configurable-item-damage-check.patch +++ b/leaves-server/minecraft-patches/features/0130-Configurable-item-damage-check.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Configurable item damage check diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index 649d17dcd7856e3b1344192d8ea4b2e9f73fc03b..cd3fbccad765a37f034977e44896fbd73e308b91 100644 +index 72f084ebb61ca5b93ddf75e9a14cc8106f908a5f..1356af3e5dfeb9f3a3bb1bcff9109d49c795729d 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -621,11 +621,11 @@ public final class ItemStack implements DataComponentHolder { +@@ -597,11 +597,11 @@ public final class ItemStack implements DataComponentHolder { } public int getDamageValue() { diff --git a/leaves-server/minecraft-patches/features/0130-Vanilla-Fluid-Pushing.patch b/leaves-server/minecraft-patches/features/0130-Vanilla-Fluid-Pushing.patch deleted file mode 100644 index cc8e1991..00000000 --- a/leaves-server/minecraft-patches/features/0130-Vanilla-Fluid-Pushing.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fortern -Date: Thu, 19 Jun 2025 00:49:24 +0800 -Subject: [PATCH] Vanilla Fluid Pushing - - -diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 529be219452fe64398f91af77ea47c5cbfe8a1df..3c9b659aa473dcc65da4aaaecb4a8132a8206b81 100644 ---- a/net/minecraft/world/entity/Entity.java -+++ b/net/minecraft/world/entity/Entity.java -@@ -4622,8 +4622,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - - final Vec3 flow = fluidState.getFlow(world, mutablePos); - -- if (diff < 0.4) { -- pushVector = pushVector.add(flow.scale(diff)); -+ // Leaves start - Vanilla Fluid Pushing -+ if (maxHeightDiff < 0.4) { -+ pushVector = pushVector.add(flow.scale(maxHeightDiff)); -+ // Leaves end - Vanilla Fluid Pushing - } else { - pushVector = pushVector.add(flow); - } diff --git a/leaves-server/minecraft-patches/features/0132-Old-Throwable-Projectile-tick-order.patch b/leaves-server/minecraft-patches/features/0131-Old-Throwable-Projectile-tick-order.patch similarity index 100% rename from leaves-server/minecraft-patches/features/0132-Old-Throwable-Projectile-tick-order.patch rename to leaves-server/minecraft-patches/features/0131-Old-Throwable-Projectile-tick-order.patch diff --git a/leaves-server/minecraft-patches/features/0132-Old-leash-behavior-when-use-firework.patch b/leaves-server/minecraft-patches/features/0132-Old-leash-behavior-when-use-firework.patch new file mode 100644 index 00000000..6f174208 --- /dev/null +++ b/leaves-server/minecraft-patches/features/0132-Old-leash-behavior-when-use-firework.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Thu, 3 Jul 2025 21:33:29 +0800 +Subject: [PATCH] Old leash behavior when use firework + + +diff --git a/net/minecraft/world/item/FireworkRocketItem.java b/net/minecraft/world/item/FireworkRocketItem.java +index c3ae57d515ca1879c5f278097435b7308436c579..9f54698ecd92ca9514ce10bc59356bcc21f77604 100644 +--- a/net/minecraft/world/item/FireworkRocketItem.java ++++ b/net/minecraft/world/item/FireworkRocketItem.java +@@ -87,7 +87,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem { + com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); + if (event.callEvent() && delayed.attemptSpawn()) { + player.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below +- if (player.dropAllLeashConnections(null)) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.keepLeashConnectWhenUseFirework && player.dropAllLeashConnections(null)) { // Leaves - Keep leash connection when using firework + level.playSound(null, player, SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F); + } + if (event.shouldConsume() && !player.hasInfiniteMaterials()) { diff --git a/leaves-server/minecraft-patches/features/0133-Old-wet-tnt-explode-behavior.patch b/leaves-server/minecraft-patches/features/0133-Old-wet-tnt-explode-behavior.patch new file mode 100644 index 00000000..a2ace95b --- /dev/null +++ b/leaves-server/minecraft-patches/features/0133-Old-wet-tnt-explode-behavior.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Fri, 4 Jul 2025 08:55:31 +0800 +Subject: [PATCH] Old wet tnt explode behavior + + +diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java +index 07e4025ca6c9c31905db2e6921138a0ded479dde..87635f6db2f1e77edc7ba6a26e9818d070a9faf7 100644 +--- a/net/minecraft/world/level/ServerExplosion.java ++++ b/net/minecraft/world/level/ServerExplosion.java +@@ -729,6 +729,7 @@ public class ServerExplosion implements Explosion { + public boolean shouldAffectBlocklikeEntities() { + boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); + boolean flag = this.source == null || this.source.getType() != EntityType.BREEZE_WIND_CHARGE && this.source.getType() != EntityType.WIND_CHARGE; ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.tntWetExplosionNoItemDamage) flag = flag && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage + return _boolean ? flag : this.blockInteraction.shouldAffectBlocklikeEntities() && flag; + } + diff --git a/leaves-server/minecraft-patches/features/0134-Old-projectile-explosion-behavior.patch b/leaves-server/minecraft-patches/features/0134-Old-projectile-explosion-behavior.patch new file mode 100644 index 00000000..37ed415b --- /dev/null +++ b/leaves-server/minecraft-patches/features/0134-Old-projectile-explosion-behavior.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Fri, 4 Jul 2025 09:11:46 +0800 +Subject: [PATCH] Old projectile explosion behavior + + +diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java +index 87635f6db2f1e77edc7ba6a26e9818d070a9faf7..b4a63faf11d4bf153d079aba5cfea7ed022891f7 100644 +--- a/net/minecraft/world/level/ServerExplosion.java ++++ b/net/minecraft/world/level/ServerExplosion.java +@@ -551,7 +551,7 @@ public class ServerExplosion implements Explosion { + // Paper end - knockback events + } + // CraftBukkit end +- entity.push(vec3); ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldProjectileExplosionBehavior) entity.setDeltaMovement(entity.getDeltaMovement().add(vec3)); else entity.push(vec3); // Leaves - old projectile explosion behavior + if (entity instanceof Player player && !player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying) && !level.paperConfig().environment.disableExplosionKnockback) { // Paper - Option to disable explosion knockback + this.hitPlayers.put(player, vec3); + } diff --git a/leaves-server/minecraft-patches/features/0135-Prevent-loss-of-item-drops-due-to-update-suppression.patch b/leaves-server/minecraft-patches/features/0135-Prevent-loss-of-item-drops-due-to-update-suppression.patch new file mode 100644 index 00000000..ef63bbbb --- /dev/null +++ b/leaves-server/minecraft-patches/features/0135-Prevent-loss-of-item-drops-due-to-update-suppression.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Fri, 4 Jul 2025 17:13:15 +0800 +Subject: [PATCH] Prevent loss of item drops due to update suppression when + breaking blocks + + +diff --git a/net/minecraft/server/level/ServerPlayerGameMode.java b/net/minecraft/server/level/ServerPlayerGameMode.java +index 48bb795216ca3fb301813080de403a048bbfa98c..711ae193ea96fd9c4cbba16a49a450444496abf1 100644 +--- a/net/minecraft/server/level/ServerPlayerGameMode.java ++++ b/net/minecraft/server/level/ServerPlayerGameMode.java +@@ -382,7 +382,14 @@ public class ServerPlayerGameMode { + this.level.captureDrops = new java.util.ArrayList<>(); + // CraftBukkit end + BlockState blockState1 = org.leavesmc.leaves.command.subcommands.BlockUpdateCommand.isNoBlockUpdate() ? blockState : block.playerWillDestroy(this.level, pos, blockState, this.player); // Leaves - no block update +- boolean flag = this.level.removeBlock(pos, false); ++ boolean flag; // Leaves start - Prevent loss of item drops due to update suppression when breaking blocks ++ org.leavesmc.leaves.util.UpdateSuppressionException ex = null; ++ try { ++ flag = this.level.removeBlock(pos, false); ++ } catch (org.leavesmc.leaves.util.UpdateSuppressionException e) { ++ ex = e; ++ flag = false; ++ } + if (flag) { + block.destroy(this.level, pos, blockState1); + } +@@ -410,6 +417,8 @@ public class ServerPlayerGameMode { + if (event.isDropItems()) { + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockDropItemEvent(bblock, state, this.player, itemsToDrop); // Paper - capture all item additions to the world + } ++ if (ex != null) throw ex; ++ // Leaves end - Prevent loss of item drops due to update suppression when breaking blocks + + // Drop event experience + if (flag) { diff --git a/leaves-server/minecraft-patches/features/0136-Fix-block-place-desync-due-to-update-suppression.patch b/leaves-server/minecraft-patches/features/0136-Fix-block-place-desync-due-to-update-suppression.patch new file mode 100644 index 00000000..1f3875ec --- /dev/null +++ b/leaves-server/minecraft-patches/features/0136-Fix-block-place-desync-due-to-update-suppression.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Sat, 5 Jul 2025 09:48:47 +0800 +Subject: [PATCH] Fix block place desync due to update suppression + + +diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java +index 1356af3e5dfeb9f3a3bb1bcff9109d49c795729d..c5ced8acc1c1f1a6b1082f3deee990d1a8a8c677 100644 +--- a/net/minecraft/world/item/ItemStack.java ++++ b/net/minecraft/world/item/ItemStack.java +@@ -389,8 +389,12 @@ public final class ItemStack implements DataComponentHolder { + } + } + InteractionResult interactionResult; ++ org.leavesmc.leaves.util.UpdateSuppressionException ue = null; + try { + interactionResult = item.useOn(context); ++ } catch (org.leavesmc.leaves.util.UpdateSuppressionException te) { ++ interactionResult = net.minecraft.world.InteractionResult.SUCCESS.configurePaper(e -> e.placedBlockAt(clickedPos.immutable())); ++ ue = te; + } finally { + serverLevel.captureBlockStates = false; + } +@@ -537,6 +541,7 @@ public final class ItemStack implements DataComponentHolder { + serverLevel.capturedBlockStates.clear(); + // CraftBukkit end + ++ if (ue != null) throw ue; + return interactionResult; + } + } diff --git a/leaves-server/minecraft-patches/features/0137-temp-fix-quick-craft.patch b/leaves-server/minecraft-patches/features/0137-temp-fix-quick-craft.patch new file mode 100644 index 00000000..e4643532 --- /dev/null +++ b/leaves-server/minecraft-patches/features/0137-temp-fix-quick-craft.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Sat, 5 Jul 2025 11:31:44 +0800 +Subject: [PATCH] temp fix quick craft + +caused by PaperMC/Paper#11765 +should remove when PaperMC/Paper#11831 merged + +diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java +index b33c78f836830dd47e275cab9c9f87531152a96b..fb6aeb0838bdf8a9b1ed406eaaa59cff6e13a855 100644 +--- a/net/minecraft/world/entity/LivingEntity.java ++++ b/net/minecraft/world/entity/LivingEntity.java +@@ -3945,11 +3945,11 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin + return null; + } else { + double d = this.getEyeY() - 0.3F; +- // Paper start +- final ItemStack tmp = stack.copy(); +- stack.setCount(0); +- stack = tmp; +- // Paper end ++ // Paper start // Leaves start - wtf this for? it breaks quick craft ++ // final ItemStack tmp = stack.copy(); ++ // stack.setCount(0); ++ // stack = tmp; ++ // Paper end // Leaves end + ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), stack); + itemEntity.setPickUpDelay(40); + if (includeThrower) { diff --git a/leaves-server/minecraft-patches/features/0138-Old-ender-dragon-part-can-use-end-portal.patch b/leaves-server/minecraft-patches/features/0138-Old-ender-dragon-part-can-use-end-portal.patch new file mode 100644 index 00000000..3e4a69ee --- /dev/null +++ b/leaves-server/minecraft-patches/features/0138-Old-ender-dragon-part-can-use-end-portal.patch @@ -0,0 +1,100 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Sun, 6 Jul 2025 10:32:36 +0800 +Subject: [PATCH] Old ender dragon part can use end portal + +This patch is Powered by CrystalCarpetAddition(https://github.com/Crystal0404/CrystalCarpetAddition) + +/* + * This file is part of the Crystal Carpet Addition project, licensed under the + * GNU General Public License v3.0 + * + * Copyright (C) 2024 Crystal0404 and contributors + * + * Crystal Carpet Addition is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Crystal Carpet Addition is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Crystal Carpet Addition. If not, see . + */ + +diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java +index 096aee98257f24ce187682c256d80b0b13611339..fc357006dcfd94656badf4f78cafb93b0b925324 100644 +--- a/net/minecraft/world/entity/Entity.java ++++ b/net/minecraft/world/entity/Entity.java +@@ -185,7 +185,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + // Paper end - Share random for entities to make them more random + public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + +- private volatile @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; // Paper - Folia schedulers - volatile ++ public volatile @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; // Paper - Folia schedulers - volatile // Leaves - private -> public + public boolean collisionLoadChunks = false; // Paper + + public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() { +@@ -3955,7 +3955,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + @Nullable + public Entity teleport(TeleportTransition teleportTransition) { + // Paper start - Fix item duplication and teleport issues +- if ((!this.isAlive() || !this.valid) && (teleportTransition.newLevel() != this.level)) { ++ if (!(org.leavesmc.leaves.LeavesConfig.modify.oldMC.enderDragonPartCanUseEndPortal && this instanceof net.minecraft.world.entity.boss.EnderDragonPart)) if ((!this.isAlive() || !this.valid) && (teleportTransition.newLevel() != this.level)) { // Leaves - endDragonPartCanUseEndPortal + LOGGER.warn("Illegal Entity Teleport {} to {}:{}", this, teleportTransition.newLevel(), teleportTransition.position(), new Throwable()); + return null; + } +@@ -4071,7 +4071,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + entityx.restoreFrom(this); + this.removeAfterChangingDimensions(); + entityx.teleportSetPosition(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); +- if (this.inWorld) newLevel.addDuringTeleport(entityx); // CraftBukkit - Don't spawn the new entity if the current entity isn't spawned ++ if (this.inWorld || (org.leavesmc.leaves.LeavesConfig.modify.oldMC.enderDragonPartCanUseEndPortal && this instanceof net.minecraft.world.entity.boss.EnderDragonPart)) newLevel.addDuringTeleport(entityx); // CraftBukkit - Don't spawn the new entity if the current entity isn't spawned // Leaves - endDragonPartCanUseEndPortal + + for (Entity entity2 : list) { + entity2.startRiding(entityx, true); +@@ -4206,6 +4206,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public boolean canTeleport(Level fromLevel, Level toLevel) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.enderDragonPartCanUseEndPortal && this instanceof net.minecraft.world.entity.boss.EnderDragonPart) return true; // Leaves - enderDragonPartCanUseEndPortal + if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowEntityPortalWithPassenger && (this.isPassenger() || this.isVehicle())) return false; // Leaves - allowEntityPortalWithPassenger + if (!this.isAlive() || !this.valid) return false; // Paper - Fix item duplication and teleport issues + if (fromLevel.dimension() == Level.END && toLevel.dimension() == Level.OVERWORLD) { +diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java +index c05803a72b5db05f9a0b6119b57f665a25e1277a..3f0077d2f1486bfac30d8161f7cc43bf719b1777 100644 +--- a/net/minecraft/world/entity/Mob.java ++++ b/net/minecraft/world/entity/Mob.java +@@ -384,6 +384,16 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + if (!this.level().isClientSide && this.tickCount % 5 == 0) { + this.updateControlFlags(); + } ++ // Leaves start - ender dragon part can use end portal ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.enderDragonPartCanUseEndPortal) return; ++ if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon dragon)) return; ++ for (net.minecraft.world.entity.boss.EnderDragonPart part : dragon.getSubEntities()) { ++ PortalProcessor portalManager = part.portalProcess; ++ if (portalManager == null) continue; ++ if (!(portalManager.portal instanceof net.minecraft.world.level.block.EndPortalBlock)) continue; ++ part.handlePortal(); ++ } ++ // Leaves end - ender dragon part can use end portal + } + + protected void updateControlFlags() { +diff --git a/net/minecraft/world/entity/PortalProcessor.java b/net/minecraft/world/entity/PortalProcessor.java +index 88b07fbb96b20124777889830afa480673629d43..250c43fb38e2aabd0b58ef44c477f07eee48bce7 100644 +--- a/net/minecraft/world/entity/PortalProcessor.java ++++ b/net/minecraft/world/entity/PortalProcessor.java +@@ -7,7 +7,7 @@ import net.minecraft.world.level.block.Portal; + import net.minecraft.world.level.portal.TeleportTransition; + + public class PortalProcessor { +- private final Portal portal; ++ public final Portal portal; // Leaves - private -> public + private BlockPos entryPosition; + private int portalTime; + private boolean insidePortalThisTick; diff --git a/leaves-server/paper-patches/features/0001-Build-changes.patch b/leaves-server/paper-patches/features/0001-Build-changes.patch index e5123cef..87779147 100644 --- a/leaves-server/paper-patches/features/0001-Build-changes.patch +++ b/leaves-server/paper-patches/features/0001-Build-changes.patch @@ -93,7 +93,7 @@ index 6abc57669e87f7f98f3b76af3c0e50825fea6eb1..c7ee6d3a158ca7d3de54bc12622affbf } } diff --git a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java -index 790bad0494454ca12ee152e3de6da3da634d9b20..c060857cb0551fff8f5033553b887f3a6b8f935a 100644 +index 74ffdc823e66fc5ec027c4b7c462382bcbfe2be2..f38f8e5851ec65a8f3f98018d55de74ea6ff165c 100644 --- a/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java +++ b/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java @@ -30,7 +30,7 @@ public record ServerBuildInfoImpl( @@ -119,10 +119,10 @@ index a7d1a959af6a810c0ce6d5baa08e4429e14d4f5b..88dbb30dd736b63f562918fb166678ba public static LiteralCommandNode create() { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index a11fc64b4933a5abce0182ba46f1da22043eb0d8..c311381d7d6841153f9f29f9a2e6718811bdf1c7 100644 +index 7675acdca2162e403f4ff523bcdd6efe0cb42d49..a950bfb0c6aeb0b19150c59cea13337005c2752a 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -232,7 +232,7 @@ public class Main { +@@ -231,7 +231,7 @@ public class Main { if (buildDate.before(deadline.getTime())) { // Paper start - This is some stupid bullshit System.err.println("*** Warning, you've not updated in a while! ***"); @@ -132,10 +132,10 @@ index a11fc64b4933a5abce0182ba46f1da22043eb0d8..c311381d7d6841153f9f29f9a2e67188 } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index a287ad5cce532229f2a514956d34a9358175bc45..27f1a050882c7b00649ab2bea2e4d00c575080eb 100644 +index c1aad9203af20102e560571435dfa75150b37c1b..ea97ea679b1ba64c9d33e52f39d010a923ef4385 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -485,7 +485,7 @@ public final class CraftMagicNumbers implements UnsafeValues { +@@ -481,7 +481,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { diff --git a/leaves-server/paper-patches/features/0003-Leaves-Server-Config-And-Command.patch b/leaves-server/paper-patches/features/0003-Leaves-Server-Config-And-Command.patch index fb55af82..9965f5c7 100644 --- a/leaves-server/paper-patches/features/0003-Leaves-Server-Config-And-Command.patch +++ b/leaves-server/paper-patches/features/0003-Leaves-Server-Config-And-Command.patch @@ -36,10 +36,10 @@ index 5c52b1563d20d7e977a5bb958c18b19dec5c365a..65664441c5692620a8b22513ded497b7 } catch (CommandException ex) { sender.sendMessage(Component.text("An internal error occurred while attempting to tab-complete this command", NamedTextColor.RED)); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 1da86b25e3b89c79d4f3920c8d2ef10ee2757f65..8dc17473e580df2ba9273e612868ad325a952bee 100644 +index 03dfcb4665d0279c825a74f3f999c92fe2bd22cb..8646070885a65bcd6e60198bdaeb538613798389 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1101,6 +1101,7 @@ public final class CraftServer implements Server { +@@ -1073,6 +1073,7 @@ public final class CraftServer implements Server { playerMetadata.removeAll(plugin); } // Paper end @@ -48,10 +48,10 @@ index 1da86b25e3b89c79d4f3920c8d2ef10ee2757f65..8dc17473e580df2ba9273e612868ad32 org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index c311381d7d6841153f9f29f9a2e6718811bdf1c7..d855a6543433ce520fb26e536f32c22b847ea0b6 100644 +index a950bfb0c6aeb0b19150c59cea13337005c2752a..7f68edab68fc82a7ae269f01633c786b2d1026a8 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java -@@ -170,6 +170,14 @@ public class Main { +@@ -169,6 +169,14 @@ public class Main { .ofType(String.class) .defaultsTo("Unknown Server") .describedAs("Name"); diff --git a/leaves-server/paper-patches/features/0004-Leaves-Protocol-Core.patch b/leaves-server/paper-patches/features/0004-Leaves-Protocol-Core.patch index dd0ca8db..5112e797 100644 --- a/leaves-server/paper-patches/features/0004-Leaves-Protocol-Core.patch +++ b/leaves-server/paper-patches/features/0004-Leaves-Protocol-Core.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Protocol Core diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8dc17473e580df2ba9273e612868ad325a952bee..4ffe2623badcaca80c192b3ea79488f274c125e9 100644 +index 8646070885a65bcd6e60198bdaeb538613798389..bd128202f1618a88b67def9c829ef7b269dad09c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -497,6 +497,7 @@ public final class CraftServer implements Server { +@@ -496,6 +496,7 @@ public final class CraftServer implements Server { this.potionBrewer = new io.papermc.paper.potion.PaperPotionBrewer(console); // Paper - custom potion mixes datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark @@ -16,7 +16,7 @@ index 8dc17473e580df2ba9273e612868ad325a952bee..4ffe2623badcaca80c192b3ea79488f2 } public boolean getCommandBlockOverride(String command) { -@@ -1108,6 +1109,7 @@ public final class CraftServer implements Server { +@@ -1080,6 +1081,7 @@ public final class CraftServer implements Server { this.spark.registerCommandBeforePlugins(this); // Paper - spark this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*"); this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions"); diff --git a/leaves-server/paper-patches/features/0005-Leaves-Fakeplayer.patch b/leaves-server/paper-patches/features/0005-Leaves-Fakeplayer.patch index 58c69748..0390b325 100644 --- a/leaves-server/paper-patches/features/0005-Leaves-Fakeplayer.patch +++ b/leaves-server/paper-patches/features/0005-Leaves-Fakeplayer.patch @@ -5,55 +5,65 @@ Subject: [PATCH] Leaves Fakeplayer 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 a589689e3a9de1fffef62e0e3dcd79bb2e848c5b..a0a6cde96322df8e455b26b32b1c593f332d4db6 100644 +index a589689e3a9de1fffef62e0e3dcd79bb2e848c5b..af9408c990d5ba2cf34d6c64db86a04c90165e91 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java +++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -41,6 +41,12 @@ class PaperEventManager { +@@ -41,6 +41,22 @@ class PaperEventManager { throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); } + // Leaves start - skip bot -+ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.Bot) { ++ if (event instanceof org.bukkit.event.player.PlayerEvent playerEvent && playerEvent.getPlayer() instanceof org.leavesmc.leaves.entity.bot.Bot) { + return; + } + // Leaves end - skip bot ++ ++ // Leaves start - process bot load/save ++ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable && org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.canResident) { ++ if (event instanceof org.bukkit.event.world.WorldLoadEvent worldLoadEvent) { ++ org.leavesmc.leaves.bot.BotList.INSTANCE.loadResume(worldLoadEvent.getWorld().getUID().toString()); ++ } else if (event instanceof org.bukkit.event.world.WorldUnloadEvent worldUnloadEvent) { ++ org.leavesmc.leaves.bot.BotList.INSTANCE.removeAllIn(worldUnloadEvent.getWorld().getUID().toString()); ++ } ++ } ++ // Leaves end - process bot load/save + HandlerList handlers = event.getHandlers(); RegisteredListener[] listeners = handlers.getRegisteredListeners(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index 1775eb659ef1a10868cfc6721aedd5096fe0a17c..1eb1a3c9736bf97fbdcd1e17a86f49c030a6cdf3 100644 +index 0a10f49ee410d93e95ceb90108200a1a9d12b54b..b836e047e9a4ae9a4cbde5caf761013d2c99e12c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -424,6 +424,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -423,6 +423,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @SuppressWarnings("unchecked") public T addEntity(T entity) { Preconditions.checkArgument(!entity.isInWorld(), "Entity has already been added to a world"); -+ Preconditions.checkState(!(entity instanceof org.leavesmc.leaves.entity.CraftBot), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!"); ++ Preconditions.checkState(!(entity instanceof org.leavesmc.leaves.entity.bot.CraftBot), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!"); net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle(); if (nmsEntity.level() != this.getHandle().getLevel()) { nmsEntity = nmsEntity.teleport(new TeleportTransition(this.getHandle().getLevel(), nmsEntity, TeleportTransition.DO_NOTHING)); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 4ffe2623badcaca80c192b3ea79488f274c125e9..25c11fbe0b4e0cdc0aa63982d185935e2016ba79 100644 +index bd128202f1618a88b67def9c829ef7b269dad09c..2a9fc317284a4e0bac4f0b64482b57de78d8bc30 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -316,6 +316,7 @@ public final class CraftServer implements Server { +@@ -315,6 +315,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; public final io.papermc.paper.SparksFly spark; private final ServerConfiguration serverConfig = new PaperServerConfiguration(); -+ private final org.leavesmc.leaves.entity.CraftBotManager botManager; // Leaves ++ private final org.leavesmc.leaves.entity.bot.CraftBotManager botManager; // Leaves // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -498,6 +499,7 @@ public final class CraftServer implements Server { +@@ -497,6 +498,7 @@ public final class CraftServer implements Server { datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark org.leavesmc.leaves.protocol.core.LeavesProtocolManager.init(); // Leaves - protocol -+ this.botManager = new org.leavesmc.leaves.entity.CraftBotManager(); // Leaves ++ this.botManager = new org.leavesmc.leaves.entity.bot.CraftBotManager(); // Leaves } public boolean getCommandBlockOverride(String command) { -@@ -1469,7 +1471,7 @@ public final class CraftServer implements Server { +@@ -1441,7 +1443,7 @@ public final class CraftServer implements Server { return false; } @@ -62,23 +72,23 @@ index 4ffe2623badcaca80c192b3ea79488f274c125e9..25c11fbe0b4e0cdc0aa63982d185935e return false; } -@@ -3209,4 +3211,11 @@ public final class CraftServer implements Server { +@@ -3186,4 +3188,11 @@ public final class CraftServer implements Server { public void allowPausing(final Plugin plugin, final boolean value) { this.console.addPluginAllowingSleep(plugin.getName(), value); } + + // Leaves start - Bot API + @Override -+ public org.leavesmc.leaves.entity.CraftBotManager getBotManager() { ++ public org.leavesmc.leaves.entity.bot.CraftBotManager getBotManager() { + return botManager; + } + // Leaves end - Bot API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index aae378697b2f2e388d2a5dfaca24c9197b8abf3e..6773681bfaf0edb03cc17bcdfa43b98c8b7c9c20 100644 +index 68351e47609ae06f0a1641b4ad2013ce6261ae4e..2d726d5878dc3033129ad30782871aae56c0595d 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -238,7 +238,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -247,7 +247,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getPlayerCount() { @@ -87,7 +97,7 @@ index aae378697b2f2e388d2a5dfaca24c9197b8abf3e..6773681bfaf0edb03cc17bcdfa43b98c } @Override -@@ -1242,9 +1242,9 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1264,9 +1264,9 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public List getPlayers() { @@ -99,7 +109,7 @@ index aae378697b2f2e388d2a5dfaca24c9197b8abf3e..6773681bfaf0edb03cc17bcdfa43b98c HumanEntity bukkitEntity = human.getBukkitEntity(); if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) { -@@ -1926,7 +1926,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1948,7 +1948,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { public void playSound(final net.kyori.adventure.sound.Sound sound) { org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper final long seed = sound.seed().orElseGet(this.world.getRandom()::nextLong); @@ -108,7 +118,7 @@ index aae378697b2f2e388d2a5dfaca24c9197b8abf3e..6773681bfaf0edb03cc17bcdfa43b98c player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player.getX(), player.getY(), player.getZ(), seed, null)); } } -@@ -1954,7 +1954,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1976,7 +1976,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper final long seed = sound.seed().orElseGet(this.getHandle().getRandom()::nextLong); if (emitter == net.kyori.adventure.sound.Sound.Emitter.self()) { @@ -117,7 +127,7 @@ index aae378697b2f2e388d2a5dfaca24c9197b8abf3e..6773681bfaf0edb03cc17bcdfa43b98c player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player, seed, null)); } } else if (emitter instanceof CraftEntity craftEntity) { -@@ -2184,7 +2184,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2206,7 +2206,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType()); } this.getHandle().sendParticlesSource( @@ -127,23 +137,23 @@ index aae378697b2f2e388d2a5dfaca24c9197b8abf3e..6773681bfaf0edb03cc17bcdfa43b98c CraftParticle.createParticleParam(particle, data), // Particle force, diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 3b41a37f852c3b494b158e447eade9b030f26556..656586dc3bda8aefc8b2e648e9f3d008cb2908fd 100644 +index b38073628d3b1381ccc4e5c6c44b2b7ec8ba1273..656d599060449a4fd53360915378aca177b7e6e7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -108,6 +108,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -121,6 +121,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return new CraftHumanEntity(server, (net.minecraft.world.entity.player.Player) entity); } -+ if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) { return new org.leavesmc.leaves.entity.CraftBot(server, bot); } ++ if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) { return new org.leavesmc.leaves.entity.bot.CraftBot(server, bot); } + // Special case complex part, since there is no extra entity type for them if (entity instanceof EnderDragonPart complexPart) { if (complexPart.parentMob instanceof EnderDragon) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 9774c9c72a910ccd919b903d92f4068c06d199d7..03778c286144d8f04147f37aa59fb73fcc584833 100644 +index 1d112510093d5eb5117adf16b92dd3411a610a4a..d74ce689380246eb176596f5905275fa5187aace 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -885,7 +885,11 @@ public class CraftEventFactory { +@@ -896,7 +896,11 @@ public class CraftEventFactory { event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable diff --git a/leaves-server/paper-patches/features/0007-MC-Technical-Survival-Mode.patch b/leaves-server/paper-patches/features/0007-MC-Technical-Survival-Mode.patch index d327f801..1aebf537 100644 --- a/leaves-server/paper-patches/features/0007-MC-Technical-Survival-Mode.patch +++ b/leaves-server/paper-patches/features/0007-MC-Technical-Survival-Mode.patch @@ -6,10 +6,10 @@ Subject: [PATCH] MC Technical Survival Mode Will automatically overwrite some configuration after startup diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -index 266932720ae0af0f17df18ad1570b29631ed2c2a..d0cd9675d166de95904fcb1767089b9430e37934 100644 +index a972eeddbdc59e53279a7c5c704e28c2fcdf7290..584e4fd53a0b78b4dbdf756c3a714c482bb7c3b8 100644 --- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java +++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -@@ -329,6 +329,7 @@ public class PaperConfigurations extends Configurations()); + } } + + // Leaves start - Bytebuf API diff --git a/leaves-server/paper-patches/features/0013-Leaves-plugin.patch b/leaves-server/paper-patches/features/0013-Leaves-plugin.patch index 818b409d..907f0cca 100644 --- a/leaves-server/paper-patches/features/0013-Leaves-plugin.patch +++ b/leaves-server/paper-patches/features/0013-Leaves-plugin.patch @@ -6,11 +6,11 @@ Subject: [PATCH] Leaves plugin This patch is licensed under the MIT license. diff --git a/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java b/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java -index 41c95f00b4b2bea6d31f85e268c33d7f6184823e..a9154645554379d80b43171562f6f64a01ed3792 100644 +index d0a4e1642d1be33cd9e832f961301ab267e216bc..417bb69104dc24bfb314799d84119fee2d7e9378 100644 --- a/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java +++ b/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java -@@ -172,28 +172,41 @@ public class PaperPluginsCommand extends BukkitCommand { - +@@ -174,28 +174,41 @@ public class PaperPluginsCommand { + final CommandSender sender = context.getSource().getSender(); final TreeMap> paperPlugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); final TreeMap> spigotPlugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + // Leaves start - leaves plugin @@ -54,7 +54,7 @@ index 41c95f00b4b2bea6d31f85e268c33d7f6184823e..a9154645554379d80b43171562f6f64a } for (final Component component : formatProviders(paperPlugins)) { -@@ -201,8 +214,9 @@ public class PaperPluginsCommand extends BukkitCommand { +@@ -203,8 +216,9 @@ public class PaperPluginsCommand { } if (!spigotPlugins.isEmpty()) { diff --git a/leaves-server/paper-patches/features/0014-Fix-SculkCatalyst-exp-skip.patch b/leaves-server/paper-patches/features/0014-Fix-SculkCatalyst-exp-skip.patch index 493379ad..9bc7ce82 100644 --- a/leaves-server/paper-patches/features/0014-Fix-SculkCatalyst-exp-skip.patch +++ b/leaves-server/paper-patches/features/0014-Fix-SculkCatalyst-exp-skip.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix SculkCatalyst exp skip diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 03778c286144d8f04147f37aa59fb73fcc584833..daea37a117101a9f3b463e87bfc8f0f9db394aca 100644 +index d74ce689380246eb176596f5905275fa5187aace..4e456eb1740a674eaf4e2ed37c16f6aa4714b11a 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -851,7 +851,7 @@ public class CraftEventFactory { +@@ -862,7 +862,7 @@ public class CraftEventFactory { CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); CraftWorld world = (CraftWorld) entity.getWorld(); @@ -17,7 +17,7 @@ index 03778c286144d8f04147f37aa59fb73fcc584833..daea37a117101a9f3b463e87bfc8f0f9 populateFields(victim, event); // Paper - make cancellable Bukkit.getServer().getPluginManager().callEvent(event); -@@ -862,6 +862,7 @@ public class CraftEventFactory { +@@ -873,6 +873,7 @@ public class CraftEventFactory { playDeathSound(victim, event, damageSource); // Paper end victim.expToDrop = event.getDroppedExp(); @@ -25,7 +25,7 @@ index 03778c286144d8f04147f37aa59fb73fcc584833..daea37a117101a9f3b463e87bfc8f0f9 lootCheck.run(); // Paper - advancement triggers before destroying items // Paper start - Restore vanilla drops behavior -@@ -901,6 +902,7 @@ public class CraftEventFactory { +@@ -912,6 +913,7 @@ public class CraftEventFactory { victim.newLevel = event.getNewLevel(); victim.newTotalExp = event.getNewTotalExp(); victim.expToDrop = event.getDroppedExp(); diff --git a/leaves-server/paper-patches/features/0015-Leaves-Config-API.patch b/leaves-server/paper-patches/features/0015-Leaves-Config-API.patch index 39743d72..f6598a18 100644 --- a/leaves-server/paper-patches/features/0015-Leaves-Config-API.patch +++ b/leaves-server/paper-patches/features/0015-Leaves-Config-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Config API diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index eb49cf958cbbd1d53f0bb4556ade8bc407ae7a20..6fbcde3248ec35d0188eea0e99922759d5f1d5cf 100644 +index 164830c0d9bae7849a4953e489ea144919d9911a..ac1632cd332f08499b7f8feb5f8c2004b89179dc 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -3238,4 +3238,11 @@ public final class CraftServer implements Server { +@@ -3215,4 +3215,11 @@ public final class CraftServer implements Server { return internalBytebufHandler; } // Leaves end - Bytebuf API diff --git a/leaves-server/paper-patches/features/0016-Old-ender-dragon-part-can-use-end-portal.patch b/leaves-server/paper-patches/features/0016-Old-ender-dragon-part-can-use-end-portal.patch new file mode 100644 index 00000000..73c57d93 --- /dev/null +++ b/leaves-server/paper-patches/features/0016-Old-ender-dragon-part-can-use-end-portal.patch @@ -0,0 +1,35 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MC_XiaoHei +Date: Sun, 6 Jul 2025 13:10:13 +0800 +Subject: [PATCH] Old ender dragon part can use end portal + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java +index 178cadf023bf516b93625c124fbf1a06b0131c58..8151542d59ceb5e135571928d2e203170f3a9ea6 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java +@@ -12,14 +12,19 @@ public class CraftComplexPart extends CraftEntity implements ComplexEntityPart { + super(server, entity); + } + +- @Override +- public EnderDragonPart getHandle() { +- return (EnderDragonPart) this.entity; +- } ++ // @Override // Leaves start - endDragonPartCanUseEndPortal ++ // public EnderDragonPart getHandle() { ++ // return (EnderDragonPart) this.entity; ++ // } + + @Override + public ComplexLivingEntity getParent() { +- return (ComplexLivingEntity) this.getHandle().parentMob.getBukkitEntity(); ++ net.minecraft.world.entity.Entity entity = this.getHandle(); ++ if (entity instanceof EnderDragonPart part) return (ComplexLivingEntity) part.parentMob.getBukkitEntity(); ++ CraftEnderDragon dragon = new org.bukkit.craftbukkit.entity.CraftEnderDragon((org.bukkit.craftbukkit.CraftServer) org.bukkit.Bukkit.getServer(), (net.minecraft.world.entity.boss.enderdragon.EnderDragon) entity); ++ entity.bukkitEntity = dragon; ++ return dragon; ++ // Leaves end - endDragonPartCanUseEndPortal + } + + @Override diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/.editorconfig b/leaves-server/src/main/java/org/leavesmc/leaves/.editorconfig index 6f086600..38a42bbb 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/.editorconfig +++ b/leaves-server/src/main/java/org/leavesmc/leaves/.editorconfig @@ -1,2 +1,7 @@ [*.java] -ij_java_use_fq_class_names = false \ No newline at end of file +ij_java_if_brace_force = always +ij_java_do_while_brace_force = always +ij_java_for_brace_force = always +ij_java_while_brace_force = always +ij_java_use_fq_class_names = false +ij_java_packages_to_use_import_on_demand = org.leavesmc.leaves.bot.agent.actions.*, org.leavesmc.leaves.bot.agent.configs.*, org.leavesmc.leaves.entity.bot.action.* \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java index fc73a01e..989bff88 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/LeavesConfig.java @@ -3,9 +3,7 @@ package org.leavesmc.leaves; import com.destroystokyo.paper.util.SneakyThrow; import io.papermc.paper.configuration.GlobalConfiguration; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import org.bukkit.command.Command; import org.bukkit.configuration.file.YamlConfiguration; @@ -29,19 +27,17 @@ import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRule; import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRules; import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeature; import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeatureSet; +import org.leavesmc.leaves.protocol.servux.logger.DataLogger; import org.leavesmc.leaves.region.RegionFileFormat; -import org.leavesmc.leaves.util.ForcePeacefulModeSwitchType; import org.leavesmc.leaves.util.MathUtils; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Random; -import java.util.Set; import java.util.function.Predicate; public final class LeavesConfig { @@ -171,21 +167,12 @@ public final class LeavesConfig { } } - @GlobalConfig("always-send-data") - public boolean canSendDataAlways = true; - @GlobalConfig("resident-fakeplayer") public boolean canResident = false; @GlobalConfig("open-fakeplayer-inventory") public boolean canOpenInventory = false; - @GlobalConfig("skip-sleep-check") - public boolean canSkipSleep = false; - - @GlobalConfig("spawn-phantom") - public boolean canSpawnPhantom = false; - @GlobalConfig("use-action") public boolean canUseAction = true; @@ -198,8 +185,46 @@ public final class LeavesConfig { @GlobalConfig(value = "cache-skin", lock = true) public boolean useSkinCache = false; - @GlobalConfig(value = "tick-type") - public ServerBot.TickType tickType = ServerBot.TickType.NETWORK; + public InGameConfig inGame = new InGameConfig(); + + @GlobalConfigCategory("in-game") + public static class InGameConfig { + + @RemovedConfig(name = "always-send-data", category = {"modify", "fakeplayer"}, transform = true) + @GlobalConfig("always-send-data") + public boolean canSendDataAlways = true; + + @RemovedConfig(name = "skip-sleep-check", category = {"modify", "fakeplayer"}, transform = true) + @GlobalConfig("skip-sleep-check") + public boolean canSkipSleep = false; + + @RemovedConfig(name = "spawn-phantom", category = {"modify", "fakeplayer"}, transform = true) + @GlobalConfig("spawn-phantom") + public boolean canSpawnPhantom = false; + + @RemovedConfig(name = "tick-type", category = {"modify", "fakeplayer"}, transform = true) + @GlobalConfig("tick-type") + public ServerBot.TickType tickType = ServerBot.TickType.NETWORK; + + @GlobalConfig(value = "simulation-distance", validator = BotSimulationDistanceValidator.class) + private int simulationDistance = -1; + + public int getSimulationDistance(ServerBot bot) { + return this.simulationDistance == -1 ? bot.getBukkitEntity().getSimulationDistance() : this.simulationDistance; + } + + public static class BotSimulationDistanceValidator extends IntConfigValidator { + @Override + public void verify(Integer old, Integer value) throws IllegalArgumentException { + if ((value < 2 && value != -1) || value > 32) { + throw new IllegalArgumentException("simulation-distance must be a number between 2 and 32, got: " + value); + } + } + } + + @GlobalConfig("enable-locator-bar") + public boolean enableLocatorBar = false; + } } public MinecraftOLDConfig oldMC = new MinecraftOLDConfig(); @@ -354,6 +379,18 @@ public final class LeavesConfig { @GlobalConfig("old-throwable-projectile-tick-order") public boolean oldThrowableProjectileTickOrder = false; + + @GlobalConfig("keep-leash-connect-when-use-firework") + public boolean keepLeashConnectWhenUseFirework = false; + + @GlobalConfig("tnt-wet-explosion-no-item-damage") + public boolean tntWetExplosionNoItemDamage = false; + + @GlobalConfig("old-projectile-explosion-behavior") + public boolean oldProjectileExplosionBehavior = false; + + @GlobalConfig("ender-dragon-part-can-use-end-portal") + public boolean enderDragonPartCanUseEndPortal = false; } public ElytraAeronauticsConfig elytraAeronautics = new ElytraAeronauticsConfig(); @@ -425,16 +462,25 @@ public final class LeavesConfig { } } - public int shulkerBoxStackSize = 1; - @GlobalConfig(value = "stackable-shulker-boxes", validator = StackableShulkerValidator.class) - private String stackableShulkerBoxes = "false"; + public ShulkerBoxConfig shulkerBox = new ShulkerBoxConfig(); - private static class StackableShulkerValidator extends StringConfigValidator { - @Override - public void verify(String old, String value) throws IllegalArgumentException { - String realValue = MathUtils.isNumeric(value) ? value : value.equals("true") ? "2" : "1"; - LeavesConfig.modify.shulkerBoxStackSize = Integer.parseInt(realValue); + @GlobalConfigCategory("shulker-box") + public static class ShulkerBoxConfig { + public int shulkerBoxStackSize = 1; + @RemovedConfig(name = "stackable-shulker-boxes", category = "modify", transform = true) + @GlobalConfig(value = "stackable-shulker-boxes", validator = StackableShulkerValidator.class) + private String stackableShulkerBoxes = "false"; + + private static class StackableShulkerValidator extends StringConfigValidator { + @Override + public void verify(String old, String value) throws IllegalArgumentException { + String realValue = MathUtils.isNumeric(value) ? value : value.equals("true") ? "2" : "1"; + LeavesConfig.modify.shulkerBox.shulkerBoxStackSize = Integer.parseInt(realValue); + } } + + @GlobalConfig(value = "same-nbt-stackable") + public boolean sameNbtStackable = false; } @GlobalConfig(value = "force-void-trade", validator = ForceVoidTradeValidator.class) @@ -846,6 +892,15 @@ public final class LeavesConfig { @GlobalConfig("hud-metadata-protocol") public boolean hudMetadataProtocol = false; + @GlobalConfig("hud-logger-protocol") + public boolean hudLoggerProtocol = false; + + @GlobalConfig("hud-enabled-loggers") + public List hudEnabledLoggers = List.of(DataLogger.Type.TPS, DataLogger.Type.MOB_CAPS); + + @GlobalConfig("hud-update-interval") + public int hudUpdateInterval = 1; + @GlobalConfig("hud-metadata-protocol-share-seed") public boolean hudMetadataShareSeed = true; @@ -956,7 +1011,7 @@ public final class LeavesConfig { public String source = "application"; public static class DownloadSourceValidator extends StringConfigValidator { - private static final List suggestSourceList = List.of("application", "cloud"); + private static List suggestSourceList = List.of("application", "cloud"); @Override public List valueSuggest() { @@ -1117,17 +1172,14 @@ public final class LeavesConfig { @GlobalConfig("vanilla-display-name") public boolean vanillaDisplayName = false; - @GlobalConfig(value = "collision-behavior") - public CollisionBehavior collisionBehavior = CollisionBehavior.BLOCK_SHAPE_VANILLA; - - public enum CollisionBehavior { - VANILLA, BLOCK_SHAPE_VANILLA, PAPER - } - @GlobalConfig("vanilla-portal-handle") public boolean vanillaPortalHandle = false; + @GlobalConfig("vanilla-fluid-pushing") + public boolean vanillaFluidPushing = true; + + @RemovedConfig(name = "collision-behavior", category = "fix") @RemovedConfig(name = "spigot-EndPlatform-destroy", category = "fix") - private final boolean spigotEndPlatformDestroy = false; + private final boolean removed = false; } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java index bc09bb05..65e116fa 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java @@ -7,9 +7,9 @@ import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.LeavesConfig; -import org.leavesmc.leaves.entity.Bot; -import org.leavesmc.leaves.entity.BotCreator; -import org.leavesmc.leaves.entity.CraftBot; +import org.leavesmc.leaves.entity.bot.Bot; +import org.leavesmc.leaves.entity.bot.BotCreator; +import org.leavesmc.leaves.entity.bot.CraftBot; import org.leavesmc.leaves.event.bot.BotCreateEvent; import org.leavesmc.leaves.plugin.MinecraftInternalPlugin; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotDataStorage.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotDataStorage.java index 6a28f733..a23420ab 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotDataStorage.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotDataStorage.java @@ -5,10 +5,14 @@ import net.minecraft.core.UUIDUtil; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtAccounter; import net.minecraft.nbt.NbtIo; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.storage.LevelResource; import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.ValueInput; import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.util.TagUtil; import org.slf4j.Logger; import java.io.File; @@ -45,7 +49,7 @@ public class BotDataStorage implements IPlayerDataStorage { public void save(Player player) { boolean flag = true; try { - CompoundTag nbt = player.saveWithoutId(new CompoundTag()); + CompoundTag nbt = TagUtil.saveEntityWithoutId(player); File file = new File(this.botDir, player.getStringUUID() + ".dat"); if (file.exists() && file.isFile()) { @@ -73,10 +77,11 @@ public class BotDataStorage implements IPlayerDataStorage { } @Override - public Optional load(Player player) { - return this.load(player.getScoreboardName(), player.getStringUUID()).map((nbt) -> { - player.load(nbt); - return nbt; + public Optional load(Player player, ProblemReporter reporter) { + return this.load(player.getScoreboardName(), player.getStringUUID()).map(nbt -> { + ValueInput valueInput = TagValueInput.create(reporter, player.registryAccess(), nbt); + player.load(valueInput); + return valueInput; }); } @@ -100,6 +105,18 @@ public class BotDataStorage implements IPlayerDataStorage { return Optional.empty(); } + public Optional read(String uuid) { + File file = new File(this.botDir, uuid + ".dat"); + if (file.exists() && file.isFile()) { + try { + return Optional.of(NbtIo.readCompressed(file.toPath(), NbtAccounter.unlimitedHeap())); + } catch (Exception exception) { + BotDataStorage.LOGGER.warn("Failed to read fakeplayer data for {}", uuid); + } + } + return Optional.empty(); + } + private void saveBotList() { try { if (this.botListFile.exists() && this.botListFile.isFile()) { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotList.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotList.java index 54d58b90..4d7af942 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotList.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotList.java @@ -14,12 +14,18 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.npc.AbstractVillager; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.ThrownEnderpearl; import net.minecraft.world.level.Level; +import net.minecraft.world.level.storage.ValueInput; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.entity.EntityRemoveEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.LeavesConfig; @@ -30,10 +36,12 @@ import org.leavesmc.leaves.event.bot.BotRemoveEvent; import org.leavesmc.leaves.event.bot.BotSpawnLocationEvent; import org.slf4j.Logger; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; @@ -50,6 +58,7 @@ public class BotList { private final Map botsByUUID = Maps.newHashMap(); private final Map botsByName = Maps.newHashMap(); + private final Map> botsNameByWorldUuid = Maps.newHashMap(); public BotList(MinecraftServer server) { this.server = server; @@ -94,15 +103,20 @@ public class BotList { ServerBot bot = new ServerBot(this.server, this.server.getLevel(Level.OVERWORLD), new GameProfile(uuid, realName)); bot.connection = new ServerBotPacketListenerImpl(this.server, bot); - Optional optional = playerIO.load(bot); + Optional optional; + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(bot.problemPath(), LOGGER)) { + optional = playerIO.load(bot, scopedCollector); + } catch (Exception e) { + throw new RuntimeException(e); + } if (optional.isEmpty()) { return null; } - CompoundTag nbt = optional.get(); + ValueInput nbt = optional.get(); ResourceKey resourcekey = null; - if (nbt.contains("WorldUUIDMost") && nbt.contains("WorldUUIDLeast")) { + if (nbt.getLong("WorldUUIDMost").isPresent() && nbt.getLong("WorldUUIDLeast").isPresent()) { org.bukkit.World bWorld = Bukkit.getServer().getWorld(new UUID(nbt.getLong("WorldUUIDMost").orElseThrow(), nbt.getLong("WorldUUIDLeast").orElseThrow())); if (bWorld != null) { resourcekey = ((CraftWorld) bWorld).getHandle().dimension(); @@ -116,8 +130,8 @@ public class BotList { return this.placeNewBot(bot, world, bot.getLocation(), nbt); } - public ServerBot placeNewBot(@NotNull ServerBot bot, ServerLevel world, Location location, @Nullable CompoundTag save) { - Optional optional = Optional.ofNullable(save); + public ServerBot placeNewBot(@NotNull ServerBot bot, ServerLevel world, Location location, ValueInput save) { + Optional optional = Optional.ofNullable(save); bot.isRealPlayer = true; bot.loginTime = System.currentTimeMillis(); @@ -129,7 +143,7 @@ public class BotList { location = event.getSpawnLocation(); bot.spawnIn(world); - bot.gameMode.setLevel(bot.serverLevel()); + bot.gameMode.setLevel(bot.level()); bot.setPosRaw(location.getX(), location.getY(), location.getZ()); bot.setRot(location.getYaw(), location.getPitch()); @@ -158,8 +172,12 @@ public class BotList { bot.renderAll(); bot.supressTrackerForLogin = false; - bot.serverLevel().getChunkSource().chunkMap.addEntity(bot); - BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.serverLevel().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ()); + bot.level().getChunkSource().chunkMap.addEntity(bot); + bot.initInventoryMenu(); + botsNameByWorldUuid + .computeIfAbsent(bot.level().uuid.toString(), (k) -> new HashSet<>()) + .add(bot.getBukkitEntity().getRealName()); + BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.level().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ()); return bot; } @@ -172,7 +190,7 @@ public class BotList { this.server.server.getPluginManager().callEvent(event); if (event.isCancelled() && event.getReason() != BotRemoveEvent.RemoveReason.INTERNAL) { - return event.isCancelled(); + return true; } if (bot.removeTaskId != -1) { @@ -180,10 +198,13 @@ public class BotList { bot.removeTaskId = -1; } + bot.disconnect(); + if (event.shouldSave()) { playerIO.save(bot); } else { bot.dropAll(true); + botsNameByWorldUuid.get(bot.level().uuid.toString()).remove(bot.getBukkitEntity().getRealName()); } if (bot.isPassenger() && event.shouldSave()) { @@ -191,8 +212,8 @@ public class BotList { if (entity.hasExactlyOnePlayerPassenger()) { bot.stopRiding(); entity.getPassengersAndSelf().forEach((entity1) -> { - if (entity1 instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { - final net.minecraft.world.entity.player.Player human = villager.getTradingPlayer(); + if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.voidTrade && entity1 instanceof AbstractVillager villager) { + final Player human = villager.getTradingPlayer(); if (human != null) { villager.setTradingPlayer(null); } @@ -203,7 +224,15 @@ public class BotList { } bot.unRide(); - bot.serverLevel().removePlayerImmediately(bot, Entity.RemovalReason.UNLOADED_WITH_PLAYER); + for (ThrownEnderpearl thrownEnderpearl : bot.getEnderPearls()) { + if (!thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) { + thrownEnderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, EntityRemoveEvent.Cause.PLAYER_QUIT); + } else { + thrownEnderpearl.setOwner(null); + } + } + + bot.level().removePlayerImmediately(bot, Entity.RemovalReason.UNLOADED_WITH_PLAYER); this.bots.remove(bot); this.botsByName.remove(bot.getScoreboardName().toLowerCase(Locale.ROOT)); @@ -214,9 +243,10 @@ public class BotList { } bot.removeTab(); - for (ServerPlayer player : bot.serverLevel().players()) { + ClientboundRemoveEntitiesPacket packet = new ClientboundRemoveEntitiesPacket(bot.getId()); + for (ServerPlayer player : bot.level().players()) { if (!(player instanceof ServerBot)) { - player.connection.send(new ClientboundRemoveEntitiesPacket(bot.getId())); + player.connection.send(packet); } } @@ -227,6 +257,15 @@ public class BotList { return true; } + public void removeAllIn(String worldUuid) { + for (String realName : this.botsNameByWorldUuid.getOrDefault(worldUuid, new HashSet<>())) { + ServerBot bot = this.getBotByName(realName); + if (bot != null) { + this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, LeavesConfig.modify.fakeplayer.canResident); + } + } + } + public void removeAll() { for (ServerBot bot : this.bots) { bot.resume = LeavesConfig.modify.fakeplayer.canResident; @@ -234,16 +273,36 @@ public class BotList { } } - public void loadResume() { - if (LeavesConfig.modify.fakeplayer.enable && LeavesConfig.modify.fakeplayer.canResident) { - CompoundTag savedBotList = this.getSavedBotList().copy(); - for (String realName : savedBotList.keySet()) { - CompoundTag nbt = savedBotList.getCompound(realName).orElseThrow(); - if (nbt.getBoolean("resume").orElse(false)) { - this.loadNewBot(realName); - } - } + public void loadBotInfo() { + if (!LeavesConfig.modify.fakeplayer.enable || !LeavesConfig.modify.fakeplayer.canResident) { + return; } + CompoundTag savedBotList = this.getSavedBotList().copy(); + for (String realName : savedBotList.keySet()) { + CompoundTag nbt = savedBotList.getCompound(realName).orElseThrow(); + if (!nbt.getBoolean("resume").orElse(false)) { + continue; + } + UUID levelUuid = BotUtil.getBotLevel(realName, this.dataStorage); + if (levelUuid == null) { + LOGGER.warn("Bot {} has no world UUID, skipping loading.", realName); + continue; + } + this.botsNameByWorldUuid + .computeIfAbsent(levelUuid.toString(), (k) -> new HashSet<>()) + .add(realName); + } + } + + public void loadResume(String worldUuid) { + if (!LeavesConfig.modify.fakeplayer.enable || !LeavesConfig.modify.fakeplayer.canResident) { + return; + } + Set bots = this.botsNameByWorldUuid.get(worldUuid); + if (bots == null) { + return; + } + bots.forEach(this::loadNewBot); } public void networkTick() { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotUtil.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotUtil.java index 6504fa29..763dd1fb 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotUtil.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/BotUtil.java @@ -2,12 +2,14 @@ package org.leavesmc.leaves.bot; import com.google.common.base.Charsets; import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.ItemStack; import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.LeavesConfig; +import java.util.Optional; import java.util.UUID; public class BotUtil { @@ -73,6 +75,21 @@ public class BotUtil { return UUID.nameUUIDFromBytes(("Fakeplayer:" + realName).getBytes(Charsets.UTF_8)); } + public static UUID getBotLevel(@NotNull String realName, BotDataStorage botDataStorage) { + UUID uuid = BotUtil.getBotUUID(realName); + Optional tagOptional = botDataStorage.read(uuid.toString()); + if (tagOptional.isEmpty()) { + return null; + } + CompoundTag tag = tagOptional.get(); + Optional worldUUIDMost = tag.getLong("WorldUUIDMost"); + Optional worldUUIDLeast = tag.getLong("WorldUUIDLeast"); + if (worldUUIDMost.isEmpty() || worldUUIDLeast.isEmpty()) { + return null; + } + return new UUID(worldUUIDMost.get(), worldUUIDLeast.get()); + } + public static String getFullName(String inputName) { return LeavesConfig.modify.fakeplayer.prefix + inputName + LeavesConfig.modify.fakeplayer.suffix; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/IPlayerDataStorage.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/IPlayerDataStorage.java index 7ebe4d6c..614fb645 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/IPlayerDataStorage.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/IPlayerDataStorage.java @@ -1,7 +1,8 @@ package org.leavesmc.leaves.bot; -import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.storage.ValueInput; import java.util.Optional; @@ -9,5 +10,5 @@ public interface IPlayerDataStorage { void save(Player player); - Optional load(Player player); + Optional load(Player player, ProblemReporter reporter); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java index d2c49f4b..569196ca 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBot.java @@ -3,10 +3,9 @@ package org.leavesmc.leaves.bot; import com.google.common.collect.ImmutableMap; import com.mojang.authlib.GameProfile; import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.event.entity.EntityKnockbackEvent; import net.minecraft.core.BlockPos; import net.minecraft.core.NonNullList; -import net.minecraft.core.particles.BlockParticleOption; -import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.StringTag; @@ -31,16 +30,16 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.PositionMoveRotation; -import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.ChestMenu; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.portal.TeleportTransition; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.phys.EntityHitResult; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -50,11 +49,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.LeavesConfig; import org.leavesmc.leaves.LeavesLogger; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; import org.leavesmc.leaves.bot.agent.AbstractBotConfig; import org.leavesmc.leaves.bot.agent.Actions; import org.leavesmc.leaves.bot.agent.Configs; -import org.leavesmc.leaves.entity.CraftBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.CraftBot; import org.leavesmc.leaves.event.bot.BotActionScheduleEvent; import org.leavesmc.leaves.event.bot.BotCreateEvent; import org.leavesmc.leaves.event.bot.BotDeathEvent; @@ -73,7 +72,7 @@ import java.util.function.Predicate; public class ServerBot extends ServerPlayer { - private final List> actions; + private final List> actions; private final Map, AbstractBotConfig> configs; public boolean resume = false; @@ -106,7 +105,8 @@ public class ServerBot extends ServerPlayer { this.tracingRange = world.spigotConfig.playerTrackingRange * world.spigotConfig.playerTrackingRange; this.notSleepTicks = 0; - this.fauxSleeping = LeavesConfig.modify.fakeplayer.canSkipSleep; + this.fauxSleeping = LeavesConfig.modify.fakeplayer.inGame.canSkipSleep; + this.getBukkitEntity().setSimulationDistance(LeavesConfig.modify.fakeplayer.inGame.getSimulationDistance(this)); this.setClientLoaded(true); } @@ -130,26 +130,18 @@ public class ServerBot extends ServerPlayer { if (this.invulnerableTime > 0) { this.invulnerableTime--; } - if (this.spawnInvulnerableTime > 0) --this.spawnInvulnerableTime; // Leaves - spawn invulnerable time + if (this.spawnInvulnerableTime > 0) { + --this.spawnInvulnerableTime; // Leaves - spawn invulnerable time + } // copy ServerPlayer end if (this.getConfigValue(Configs.SPAWN_PHANTOM)) { this.notSleepTicks++; } - if (LeavesConfig.modify.fakeplayer.regenAmount > 0.0 && server.getTickCount() % 20 == 0) { - float health = getHealth(); - float maxHealth = getMaxHealth(); + if (LeavesConfig.modify.fakeplayer.regenAmount > 0.0 && getServer().getTickCount() % 20 == 0) { float regenAmount = (float) (LeavesConfig.modify.fakeplayer.regenAmount * 20); - float amount; - - if (health < maxHealth - regenAmount) { - amount = health + regenAmount; - } else { - amount = maxHealth; - } - - this.setHealth(amount); + this.setHealth(Math.min(this.getHealth() + regenAmount, this.getMaxHealth())); } if (this.getConfigValue(Configs.TICK_TYPE) == TickType.ENTITY_LIST) { @@ -194,7 +186,7 @@ public class ServerBot extends ServerPlayer { this.updateIsUnderwater(); if (this.getConfigValue(Configs.TICK_TYPE) == TickType.NETWORK) { - this.server.scheduleOnMain(this::runAction); + this.getServer().scheduleOnMain(this::runAction); } this.livingEntityTick(); @@ -227,6 +219,11 @@ public class ServerBot extends ServerPlayer { } } + @Override + public boolean canSimulateMovement() { + return true; + } + @Override public @Nullable ServerBot teleport(@NotNull TeleportTransition teleportTransition) { if (this.isSleeping() || this.isRemoved()) { @@ -236,7 +233,7 @@ public class ServerBot extends ServerPlayer { this.removeVehicle(); } - ServerLevel fromLevel = this.serverLevel(); + ServerLevel fromLevel = this.level(); ServerLevel toLevel = teleportTransition.newLevel(); if (toLevel.dimension() == fromLevel.dimension()) { @@ -273,6 +270,14 @@ public class ServerBot extends ServerPlayer { return this; } + @Override + public void knockback(double strength, double x, double z, @Nullable Entity attacker, EntityKnockbackEvent.@NotNull Cause eventCause) { + if (!this.hurtMarked) { + return; + } + super.knockback(strength, x, z, attacker, eventCause); + } + @Override public void onItemPickup(@NotNull ItemEntity item) { super.onItemPickup(item); @@ -296,7 +301,7 @@ public class ServerBot extends ServerPlayer { if (LeavesConfig.modify.fakeplayer.canOpenInventory) { if (player instanceof ServerPlayer player1 && player.getMainHandItem().isEmpty()) { BotInventoryOpenEvent event = new BotInventoryOpenEvent(this.getBukkitEntity(), player1.getBukkitEntity()); - this.server.server.getPluginManager().callEvent(event); + this.getServer().server.getPluginManager().callEvent(event); if (!event.isCancelled()) { player.openMenu(new SimpleMenuProvider((i, inventory, p) -> ChestMenu.sixRows(i, inventory, this.container), this.getDisplayName())); return InteractionResult.SUCCESS; @@ -306,49 +311,6 @@ public class ServerBot extends ServerPlayer { return super.interact(player, hand); } - @Override - public void checkFallDamage(double y, boolean onGround, @NotNull BlockState state, @NotNull BlockPos pos) { - ServerLevel serverLevel = this.serverLevel(); - if (!this.isInWater() && y < 0.0) { - this.fallDistance -= (float) y; - } - if (onGround && this.fallDistance > 0.0F) { - this.onChangedBlock(serverLevel, pos); - double attributeValue = this.getAttributeValue(Attributes.SAFE_FALL_DISTANCE); - if (this.fallDistance > attributeValue && !state.isAir()) { - double x = this.getX(); - double y1 = this.getY(); - double z = this.getZ(); - BlockPos blockPos = this.blockPosition(); - if (pos.getX() != blockPos.getX() || pos.getZ() != blockPos.getZ()) { - double d = x - pos.getX() - 0.5; - double d1 = z - pos.getZ() - 0.5; - double max = Math.max(Math.abs(d), Math.abs(d1)); - x = pos.getX() + 0.5 + d / max * 0.5; - z = pos.getZ() + 0.5 + d1 / max * 0.5; - } - - float f = Mth.ceil(this.fallDistance - attributeValue); - double min = Math.min(0.2F + f / 15.0F, 2.5); - int i = (int) (150.0 * min); - serverLevel.sendParticlesSource(this, new BlockParticleOption(ParticleTypes.BLOCK, state), false, false, x, y1, z, i, 0.0, 0.0, 0.0, 0.15F); - } - } - - if (onGround) { - if (this.fallDistance > 0.0F) { - state.getBlock().fallOn(serverLevel, state, pos, this, this.fallDistance); - serverLevel.gameEvent(GameEvent.HIT_GROUND, this.position(), - GameEvent.Context.of(this, this.mainSupportingBlockPos.map(supportingPos -> this.level().getBlockState(supportingPos)).orElse(state)) - ); - } - - this.resetFallDistance(); - } else if (y < 0.0D) { - this.fallDistance -= (float) y; - } - } - @Override public void attack(@NotNull Entity target) { super.attack(target); @@ -356,7 +318,7 @@ public class ServerBot extends ServerPlayer { } @Override - public void addAdditionalSaveData(@NotNull CompoundTag nbt) { + public void addAdditionalSaveData(@NotNull ValueOutput nbt) { super.addAdditionalSaveData(nbt); nbt.putBoolean("isShiftKeyDown", this.isShiftKeyDown()); @@ -373,31 +335,29 @@ public class ServerBot extends ServerPlayer { createNbt.put("skin", skin); } - nbt.put("createStatus", createNbt); + nbt.store("createStatus", CompoundTag.CODEC, createNbt); if (!this.actions.isEmpty()) { - ListTag actionNbt = new ListTag(); - for (AbstractBotAction action : this.actions) { + ValueOutput.TypedOutputList actionNbt = nbt.list("actions", CompoundTag.CODEC); + for (ServerBotAction action : this.actions) { actionNbt.add(action.save(new CompoundTag())); } - nbt.put("actions", actionNbt); } if (!this.configs.isEmpty()) { - ListTag configNbt = new ListTag(); + ValueOutput.TypedOutputList configNbt = nbt.list("configs", CompoundTag.CODEC); for (AbstractBotConfig config : this.configs.values()) { configNbt.add(config.save(new CompoundTag())); } - nbt.put("configs", configNbt); } } @Override - public void readAdditionalSaveData(@NotNull CompoundTag nbt) { + public void readAdditionalSaveData(@NotNull ValueInput nbt) { super.readAdditionalSaveData(nbt); - this.setShiftKeyDown(nbt.getBoolean("isShiftKeyDown").orElse(false)); + this.setShiftKeyDown(nbt.getBooleanOr("isShiftKeyDown", false)); - CompoundTag createNbt = nbt.getCompound("createStatus").orElseThrow(); + CompoundTag createNbt = nbt.read("createStatus", CompoundTag.CODEC).orElseThrow(); BotCreateState.Builder createBuilder = BotCreateState.builder(createNbt.getString("realName").orElseThrow(), null).name(createNbt.getString("name").orElseThrow()); String[] skin = null; @@ -416,23 +376,21 @@ public class ServerBot extends ServerPlayer { this.gameProfile = new BotList.CustomGameProfile(this.getUUID(), this.createState.name(), this.createState.skin()); - if (nbt.contains("actions")) { - ListTag actionNbt = nbt.getList("actions").orElseThrow(); - for (int i = 0; i < actionNbt.size(); i++) { - CompoundTag actionTag = actionNbt.getCompound(i).orElseThrow(); - AbstractBotAction action = Actions.getForName(actionTag.getString("actionName").orElseThrow()); + if (nbt.list("actions", CompoundTag.CODEC).isPresent()) { + ValueInput.TypedInputList actionNbt = nbt.list("actions", CompoundTag.CODEC).orElseThrow(); + actionNbt.forEach(actionTag -> { + ServerBotAction action = Actions.getForName(actionTag.getString("actionName").orElseThrow()); if (action != null) { - AbstractBotAction newAction = action.create(); + ServerBotAction newAction = action.create(); newAction.load(actionTag); this.actions.add(newAction); } - } + }); } - if (nbt.contains("configs")) { - ListTag configNbt = nbt.getList("configs").orElseThrow(); - for (int i = 0; i < configNbt.size(); i++) { - CompoundTag configTag = configNbt.getCompound(i).orElseThrow(); + if (nbt.list("configs", CompoundTag.CODEC).isPresent()) { + ValueInput.TypedInputList configNbt = nbt.list("configs", CompoundTag.CODEC).orElseThrow(); + for (CompoundTag configTag : configNbt) { Configs configKey = Configs.getConfig(configTag.getString("configName").orElseThrow()); if (configKey != null) { this.configs.get(configKey).load(configTag); @@ -441,11 +399,6 @@ public class ServerBot extends ServerPlayer { } } - @Override - public boolean isClientAuthoritative() { - return false; - } - public void sendPlayerInfo(ServerPlayer player) { player.connection.send(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED, ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME), List.of(this))); } @@ -461,7 +414,7 @@ public class ServerBot extends ServerPlayer { } public void sendFakeData(ServerPlayerConnection playerConnection, boolean login) { - ChunkMap.TrackedEntity entityTracker = ((ServerLevel) this.level()).getChunkSource().chunkMap.entityMap.get(this.getId()); + ChunkMap.TrackedEntity entityTracker = this.level().getChunkSource().chunkMap.entityMap.get(this.getId()); if (entityTracker == null) { LeavesLogger.LOGGER.warning("Fakeplayer cant get entity tracker for " + this.getId()); @@ -477,7 +430,7 @@ public class ServerBot extends ServerPlayer { } public void renderAll() { - this.server.getPlayerList().getPlayers().forEach( + this.getServer().getPlayerList().getPlayers().forEach( player -> { this.sendPlayerInfo(player); this.sendFakeDataIfNeed(player, false); @@ -486,16 +439,16 @@ public class ServerBot extends ServerPlayer { } private void sendPacket(Packet packet) { - this.server.getPlayerList().getPlayers().forEach(player -> player.connection.send(packet)); + this.getServer().getPlayerList().getPlayers().forEach(player -> player.connection.send(packet)); } @Override public void die(@NotNull DamageSource damageSource) { - boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); + boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); Component defaultMessage = this.getCombatTracker().getDeathMessage(); BotDeathEvent event = new BotDeathEvent(this.getBukkitEntity(), PaperAdventure.asAdventure(defaultMessage), flag); - this.server.server.getPluginManager().callEvent(event); + this.getServer().server.getPluginManager().callEvent(event); if (event.isCancelled()) { if (this.getHealth() <= 0) { @@ -508,10 +461,10 @@ public class ServerBot extends ServerPlayer { net.kyori.adventure.text.Component deathMessage = event.deathMessage(); if (event.isSendDeathMessage() && deathMessage != null && !deathMessage.equals(net.kyori.adventure.text.Component.empty())) { - this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(deathMessage), false); + this.getServer().getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(deathMessage), false); } - this.server.getBotList().removeBot(this, BotRemoveEvent.RemoveReason.DEATH, null, false); + this.getServer().getBotList().removeBot(this, BotRemoveEvent.RemoveReason.DEATH, null, false); } public void removeTab() { @@ -578,11 +531,11 @@ public class ServerBot extends ServerPlayer { private void runAction() { if (LeavesConfig.modify.fakeplayer.canUseAction) { this.actions.forEach(action -> action.tryTick(this)); - this.actions.removeIf(AbstractBotAction::isCancelled); + this.actions.removeIf(ServerBotAction::isCancelled); } } - public boolean addBotAction(AbstractBotAction action, CommandSender sender) { + public boolean addBotAction(ServerBotAction action, CommandSender sender) { if (!LeavesConfig.modify.fakeplayer.canUseAction) { return false; } @@ -596,7 +549,7 @@ public class ServerBot extends ServerPlayer { return true; } - public List> getBotActions() { + public List> getBotActions() { return actions; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBotPacketListenerImpl.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBotPacketListenerImpl.java index c62f9258..35fb17ff 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBotPacketListenerImpl.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/ServerBotPacketListenerImpl.java @@ -1,14 +1,13 @@ package org.leavesmc.leaves.bot; +import io.netty.channel.ChannelFutureListener; import net.minecraft.network.Connection; import net.minecraft.network.DisconnectionDetails; -import net.minecraft.network.PacketSendListener; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.network.ServerGamePacketListenerImpl; -import org.bukkit.event.player.PlayerKickEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,19 +18,11 @@ public class ServerBotPacketListenerImpl extends ServerGamePacketListenerImpl { } @Override - public void sendPacket(@NotNull Packet packet) { + public void send(@NotNull Packet packet, @Nullable ChannelFutureListener listener) { } @Override - public void send(@NotNull Packet packet) { - } - - @Override - public void send(@NotNull Packet packet, @Nullable PacketSendListener callbacks) { - } - - @Override - public void disconnect(@NotNull DisconnectionDetails disconnectionInfo, PlayerKickEvent.@NotNull Cause cause) { + public void disconnect(@NotNull DisconnectionDetails disconnectionInfo) { } @Override @@ -71,15 +62,7 @@ public class ServerBotPacketListenerImpl extends ServerGamePacketListenerImpl { } @Override - public void send(@NotNull Packet packet) { - } - - @Override - public void send(@NotNull Packet packet, @Nullable PacketSendListener packetsendlistener) { - } - - @Override - public void send(@NotNull Packet packet, @Nullable PacketSendListener callbacks, boolean flush) { + public void send(@NotNull Packet packet, @javax.annotation.Nullable ChannelFutureListener channelFutureListener, boolean flag) { } } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java index b7c53402..5b831b65 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Actions.java @@ -3,23 +3,8 @@ package org.leavesmc.leaves.bot.agent; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.agent.actions.AttackAction; -import org.leavesmc.leaves.bot.agent.actions.BreakBlockAction; -import org.leavesmc.leaves.bot.agent.actions.DropAction; -import org.leavesmc.leaves.bot.agent.actions.FishAction; -import org.leavesmc.leaves.bot.agent.actions.JumpAction; -import org.leavesmc.leaves.bot.agent.actions.LookAction; -import org.leavesmc.leaves.bot.agent.actions.RotateAction; -import org.leavesmc.leaves.bot.agent.actions.RotationAction; -import org.leavesmc.leaves.bot.agent.actions.ShootAction; -import org.leavesmc.leaves.bot.agent.actions.SneakAction; -import org.leavesmc.leaves.bot.agent.actions.SwimAction; -import org.leavesmc.leaves.bot.agent.actions.UseItemAction; -import org.leavesmc.leaves.bot.agent.actions.UseItemOffHandAction; -import org.leavesmc.leaves.bot.agent.actions.UseItemOnAction; -import org.leavesmc.leaves.bot.agent.actions.UseItemOnOffhandAction; -import org.leavesmc.leaves.bot.agent.actions.UseItemToAction; -import org.leavesmc.leaves.bot.agent.actions.UseItemToOffhandAction; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; import java.util.Collection; import java.util.HashMap; @@ -28,57 +13,62 @@ import java.util.Set; public class Actions { - private static final Map> actions = new HashMap<>(); + private static final Map> actionsByName = new HashMap<>(); + private static final Map, ServerBotAction> actionsByClass = new HashMap<>(); public static void registerAll() { - register(new AttackAction()); - register(new BreakBlockAction()); - register(new DropAction()); - register(new JumpAction()); - register(new RotateAction()); - register(new SneakAction()); - register(new UseItemAction()); - register(new UseItemOnAction()); - register(new UseItemToAction()); - register(new LookAction()); - register(new FishAction()); - register(new SwimAction()); - register(new UseItemOffHandAction()); - register(new UseItemOnOffhandAction()); - register(new UseItemToOffhandAction()); - register(new RotationAction()); - register(new ShootAction()); + register(new ServerAttackAction(), AttackAction.class); + register(new ServerBreakBlockAction(), BreakBlockAction.class); + register(new ServerDropAction(), DropAction.class); + register(new ServerJumpAction(), JumpAction.class); + register(new ServerSneakAction(), SneakAction.class); + register(new ServerUseItemAutoAction(), UseItemAutoAction.class); + register(new ServerUseItemAction(), UseItemAction.class); + register(new ServerUseItemOnAction(), UseItemOnAction.class); + register(new ServerUseItemToAction(), UseItemToAction.class); + register(new ServerUseItemOffhandAction(), UseItemOffhandAction.class); + register(new ServerUseItemOnOffhandAction(), UseItemOnOffhandAction.class); + register(new ServerUseItemToOffhandAction(), UseItemToOffhandAction.class); + register(new ServerLookAction.TO(), LookAction.class); + register(new ServerLookAction.ON(), LookAction.class); + register(new ServerFishAction(), FishAction.class); + register(new ServerSwimAction(), SwimAction.class); + register(new ServerRotationAction(), RotationAction.class); + register(new ServerMoveAction(), MoveAction.class); } - public static boolean register(@NotNull AbstractBotAction action) { - if (!actions.containsKey(action.getName())) { - actions.put(action.getName(), action); + public static boolean register(@NotNull ServerBotAction action, Class> type) { + if (!actionsByName.containsKey(action.getName())) { + actionsByName.put(action.getName(), action); + actionsByClass.put(type, action); return true; } return false; } public static boolean unregister(@NotNull String name) { - if (actions.containsKey(name)) { - actions.remove(name); - return true; - } - return false; + // TODO add in custom action api + return true; } @NotNull @Contract(pure = true) - public static Collection> getAll() { - return actions.values(); + public static Collection> getAll() { + return actionsByName.values(); } @NotNull public static Set getNames() { - return actions.keySet(); + return actionsByName.keySet(); } @Nullable - public static AbstractBotAction getForName(String name) { - return actions.get(name); + public static ServerBotAction getForName(String name) { + return actionsByName.get(name); + } + + @Nullable + public static ServerBotAction getForClass(@NotNull Class type) { + return actionsByClass.get(type); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Configs.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Configs.java index b602e9e3..c2299cf8 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Configs.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/Configs.java @@ -4,11 +4,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.configs.AlwaysSendDataConfig; -import org.leavesmc.leaves.bot.agent.configs.SimulationDistanceConfig; -import org.leavesmc.leaves.bot.agent.configs.SkipSleepConfig; -import org.leavesmc.leaves.bot.agent.configs.SpawnPhantomConfig; -import org.leavesmc.leaves.bot.agent.configs.TickTypeConfig; +import org.leavesmc.leaves.bot.agent.configs.*; import java.util.Collection; import java.util.HashMap; @@ -25,6 +21,7 @@ public class Configs { public static final Configs SPAWN_PHANTOM = register(SpawnPhantomConfig.class, SpawnPhantomConfig::new); public static final Configs SIMULATION_DISTANCE = register(SimulationDistanceConfig.class, SimulationDistanceConfig::new); public static final Configs TICK_TYPE = register(TickTypeConfig.class, TickTypeConfig::new); + public static final Configs ENABLE_LOCATOR_BAR = register(LocatorBarConfig.class, LocatorBarConfig::new); private final Class> configClass; private final Supplier> configCreator; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftBotAction.java deleted file mode 100644 index 27f2f46d..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftBotAction.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import org.bukkit.craftbukkit.entity.CraftPlayer; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.bot.agent.Actions; -import org.leavesmc.leaves.entity.botaction.BotActionType; -import org.leavesmc.leaves.entity.botaction.LeavesBotAction; - -public class CraftBotAction extends LeavesBotAction { - - private final AbstractBotAction handle; - - public CraftBotAction(@NotNull AbstractBotAction action) { - super(BotActionType.valueOf(action.getName()), action.getInitialTickInterval(), action.getNumberRemaining()); - this.handle = action; - } - - @Contract("_ -> new") - @NotNull - public static LeavesBotAction asAPICopy(AbstractBotAction action) { - return new CraftBotAction(action); - } - - @NotNull - public static AbstractBotAction asInternalCopy(@NotNull LeavesBotAction action) { - AbstractBotAction act = Actions.getForName(action.getActionName()); - if (act == null) { - throw new IllegalArgumentException("Invalid action name!"); - } - - AbstractBotAction newAction = null; - String[] args = new String[]{String.valueOf(action.getInitialTickDelay()), String.valueOf(action.getInitialTickInterval()), String.valueOf(action.getInitialNumber())}; - try { - if (act instanceof CraftCustomBotAction customBotAction) { - newAction = customBotAction.createCraft(action.getActionPlayer(), args); - } else { - newAction = act.create(); - newAction.loadCommand(action.getActionPlayer() == null ? null : ((CraftPlayer) action.getActionPlayer()).getHandle(), act.getArgument().parse(0, args)); - } - } catch (IllegalArgumentException ignore) { - } - - if (newAction == null) { - throw new IllegalArgumentException("Invalid action!"); // TODO look action - } - return newAction; - } - - public AbstractBotAction getHandle() { - return handle; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java deleted file mode 100644 index bb96d671..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/CraftCustomBotAction.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.server.level.ServerPlayer; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.command.CommandArgument; -import org.leavesmc.leaves.command.CommandArgumentResult; -import org.leavesmc.leaves.entity.botaction.CustomBotAction; - -public class CraftCustomBotAction extends AbstractBotAction { - - private final CustomBotAction realAction; - - public CraftCustomBotAction(String name, @NotNull CustomBotAction realAction) { - super(name, CommandArgument.EMPTY, null); - this.realAction = realAction; - } - - @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - throw new UnsupportedOperationException("Not supported."); - } - - public CraftCustomBotAction createCraft(@Nullable Player player, String[] args) { - CustomBotAction newRealAction = realAction.getNew(player, args); - if (newRealAction != null) { - return new CraftCustomBotAction(this.getName(), newRealAction); - } - return null; - } - - @Override - public int getInitialNumber() { - return realAction.getInitialNumber(); - } - - @Override - public int getInitialTickDelay() { - return realAction.getInitialTickDelay(); - } - - @Override - public int getInitialTickInterval() { - return realAction.getInitialTickInterval(); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - return realAction.doTick(bot.getBukkitEntity()); - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/DropAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/DropAction.java deleted file mode 100644 index 9609a46f..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/DropAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; - -public class DropAction extends AbstractTimerAction { - - public DropAction() { - super("drop", DropAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - bot.dropAll(false); - return true; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/JumpAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/JumpAction.java deleted file mode 100644 index 6fc9ba9b..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/JumpAction.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; - -public class JumpAction extends AbstractTimerAction { - - public JumpAction() { - super("jump", JumpAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - if (bot.onGround()) { - bot.jumpFromGround(); - return true; - } else { - return false; - } - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/LookAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/LookAction.java deleted file mode 100644 index d80f6059..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/LookAction.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerPlayer; -import org.apache.commons.lang3.tuple.Pair; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.command.CommandArgument; -import org.leavesmc.leaves.command.CommandArgumentResult; -import org.leavesmc.leaves.command.CommandArgumentType; - -import java.text.DecimalFormat; -import java.util.List; - -public class LookAction extends AbstractBotAction { - - private static final DecimalFormat DF = new DecimalFormat("0.0"); - - public LookAction() { - super("look", CommandArgument.of(CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE, CommandArgumentType.DOUBLE), LookAction::new); - this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getX())), "") : Pair.of(List.of("0"), "")); - this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getY())), "") : Pair.of(List.of("0"), "")); - this.setSuggestion(2, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getZ())), "") : Pair.of(List.of("0"), "")); - } - - private Vector pos; - - @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) throws IllegalArgumentException { - Vector pos = result.readVector(); - if (pos != null) { - this.setPos(pos).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1); - } else { - throw new IllegalArgumentException("pos?"); - } - } - - @Override - @NotNull - public CompoundTag save(@NotNull CompoundTag nbt) { - super.save(nbt); - nbt.putDouble("x", this.pos.getX()); - nbt.putDouble("y", this.pos.getY()); - nbt.putDouble("z", this.pos.getZ()); - return nbt; - } - - @Override - public void load(@NotNull CompoundTag nbt) { - super.load(nbt); - this.setPos( - new Vector( - nbt.getDouble("x").orElse(0.0), - nbt.getDouble("y").orElse(0.0), - nbt.getDouble("z").orElse(0.0) - ) - ); - } - - public LookAction setPos(Vector pos) { - this.pos = pos; - return this; - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - bot.look(pos.subtract(bot.getLocation().toVector()), false); - return true; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/RotateAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/RotateAction.java deleted file mode 100644 index 8d902607..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/RotateAction.java +++ /dev/null @@ -1,51 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerPlayer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.command.CommandArgument; -import org.leavesmc.leaves.command.CommandArgumentResult; - -public class RotateAction extends AbstractBotAction { - - public RotateAction() { - super("rotate", CommandArgument.EMPTY, RotateAction::new); - } - - private ServerPlayer player; - - @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - this.setPlayer(player).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1); - } - - public RotateAction setPlayer(ServerPlayer player) { - this.player = player; - return this; - } - - @Override - @NotNull - public CompoundTag save(@NotNull CompoundTag nbt) { - super.save(nbt); - nbt.putString("actionName", "look"); // to player loc - nbt.putDouble("x", player.getX()); - nbt.putDouble("y", player.getY()); - nbt.putDouble("z", player.getZ()); - return nbt; - } - - @Override - public void load(@NotNull CompoundTag nbt) { - throw new UnsupportedOperationException("Not supported."); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - bot.faceLocation(player.getBukkitEntity().getLocation()); - return true; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/AttackAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerAttackAction.java similarity index 52% rename from leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/AttackAction.java rename to leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerAttackAction.java index 6c66ef29..b9008520 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/AttackAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerAttackAction.java @@ -3,20 +3,27 @@ package org.leavesmc.leaves.bot.agent.actions; import net.minecraft.world.entity.Entity; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.entity.bot.actions.CraftAttackAction; -public class AttackAction extends AbstractTimerAction { +public class ServerAttackAction extends ServerTimerBotAction { - public AttackAction() { - super("attack", AttackAction::new); + public ServerAttackAction() { + super("attack", ServerAttackAction::new); } @Override public boolean doTick(@NotNull ServerBot bot) { Entity entity = bot.getTargetEntity(3, target -> target.isAttackable() && !target.skipAttackInteraction(bot)); - if (entity != null) { + if (entity == null) { + return false; + } else { bot.attack(entity); return true; } - return false; + } + + @Override + public Object asCraft() { + return new CraftAttackAction(this); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/AbstractBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerBotAction.java similarity index 64% rename from leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/AbstractBotAction.java rename to leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerBotAction.java index 72ea8fc5..73e92fd8 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/AbstractBotAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerBotAction.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.bot.agent; +package org.leavesmc.leaves.bot.agent.actions; import net.minecraft.core.UUIDUtil; import net.minecraft.nbt.CompoundTag; @@ -6,7 +6,6 @@ import net.minecraft.server.level.ServerPlayer; import org.apache.commons.lang3.tuple.Pair; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.command.CommandArgumentResult; @@ -16,10 +15,11 @@ import org.leavesmc.leaves.event.bot.BotActionStopEvent; import java.util.List; import java.util.UUID; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Supplier; -//TODO onStop for fully terminate action (use, etc.) -public abstract class AbstractBotAction> { +@SuppressWarnings("unchecked") +public abstract class ServerBotAction> { private final String name; private final CommandArgument argument; @@ -34,20 +34,29 @@ public abstract class AbstractBotAction> { private int numberRemaining; private boolean cancel; - public AbstractBotAction(String name, CommandArgument argument, Supplier creator) { + private Consumer onFail; + private Consumer onSuccess; + private Consumer onStop; + + public ServerBotAction(String name, CommandArgument argument, Supplier creator) { this.name = name; this.argument = argument; this.uuid = UUID.randomUUID(); this.creator = creator; this.cancel = false; - this.initialTickInterval = 20; - this.initialNumber = -1; + this.setStartDelayTick(0); + this.setDoIntervalTick(1); + this.setDoNumber(1); } + public abstract boolean doTick(@NotNull ServerBot bot); + + public abstract Object asCraft(); + public void init() { this.tickToNext = initialTickDelay; - this.numberRemaining = this.getInitialNumber(); + this.numberRemaining = this.getDoNumber(); this.setCancelled(false); } @@ -57,18 +66,23 @@ public abstract class AbstractBotAction> { return; } + if (this.cancel) { + this.stop(bot, BotActionStopEvent.Reason.PLUGIN); + return; + } + if (this.tickToNext <= 0) { BotActionExecuteEvent event = new BotActionExecuteEvent(bot.getBukkitEntity(), name, uuid); event.callEvent(); if (event.getResult() == BotActionExecuteEvent.Result.SOFT_CANCEL) { - this.tickToNext = this.getInitialTickInterval() - 1; + this.tickToNext = this.getDoIntervalTick() - 1; return; } else if (event.getResult() == BotActionExecuteEvent.Result.HARD_CANCEL) { if (this.numberRemaining > 0) { this.numberRemaining--; } - this.tickToNext = this.getInitialTickInterval() - 1; + this.tickToNext = this.getDoIntervalTick() - 1; return; } @@ -76,7 +90,12 @@ public abstract class AbstractBotAction> { if (this.numberRemaining > 0) { this.numberRemaining--; } - this.tickToNext = this.getInitialTickInterval() - 1; + this.tickToNext = this.getDoIntervalTick() - 1; + if (this.onSuccess != null) { + this.onSuccess.accept((E) this); + } + } else if (this.onFail != null) { + this.onFail.accept((E) this); } } else { this.tickToNext--; @@ -113,24 +132,33 @@ public abstract class AbstractBotAction> { public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { new BotActionStopEvent(bot.getBukkitEntity(), this.name, this.uuid, reason, null).callEvent(); this.setCancelled(true); + if (this.onStop != null) { + this.onStop.accept((E) this); + } } - public abstract void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result); + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + } - public abstract boolean doTick(@NotNull ServerBot bot); - - @SuppressWarnings("unchecked") - public E setSuggestion(int n, BiFunction, String>> suggestion) { + public void setSuggestion(int n, BiFunction, String>> suggestion) { this.argument.setSuggestion(n, suggestion); - return (E) this; } - public E setSuggestion(int n, Pair, String> suggestion) { - return this.setSuggestion(n, (sender, arg) -> suggestion); + public void setSuggestion(int n, Pair, String> suggestion) { + this.setSuggestion(n, (sender, arg) -> suggestion); } - public E setSuggestion(int n, List tabComplete) { - return this.setSuggestion(n, Pair.of(tabComplete, null)); + public void setSuggestion(int n, List tabComplete) { + this.setSuggestion(n, Pair.of(tabComplete, null)); + } + + @NotNull + public E create() { + return this.creator.get(); + } + + public CommandArgument getArgument() { + return this.argument; } public String getName() { @@ -141,41 +169,35 @@ public abstract class AbstractBotAction> { return uuid; } - @SuppressWarnings("unchecked") - public E setInitialTickDelay(int initialTickDelay) { + public void setStartDelayTick(int initialTickDelay) { this.initialTickDelay = initialTickDelay; - return (E) this; } - public int getInitialTickDelay() { + public int getStartDelayTick() { return this.initialTickDelay; } - public int getInitialTickInterval() { + public void setDoIntervalTick(int initialTickInterval) { + this.initialTickInterval = Math.max(1, initialTickInterval); + } + + public int getDoIntervalTick() { return this.initialTickInterval; } - @SuppressWarnings("unchecked") - public E setInitialTickInterval(int initialTickInterval) { - this.initialTickInterval = Math.max(1, initialTickInterval); - return (E) this; - } - - public int getInitialNumber() { - return this.initialNumber; - } - - @SuppressWarnings("unchecked") - public E setInitialNumber(int initialNumber) { + public void setDoNumber(int initialNumber) { this.initialNumber = Math.max(-1, initialNumber); - return (E) this; + } + + public int getDoNumber() { + return this.initialNumber; } public int getTickToNext() { return this.tickToNext; } - public int getNumberRemaining() { + public int getDoNumberRemaining() { return this.numberRemaining; } @@ -187,12 +209,27 @@ public abstract class AbstractBotAction> { this.cancel = cancel; } - public CommandArgument getArgument() { - return this.argument; + public void setOnFail(Consumer onFail) { + this.onFail = onFail; } - @NotNull - public E create() { - return this.creator.get(); + public Consumer getOnFail() { + return onFail; + } + + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + } + + public Consumer getOnSuccess() { + return onSuccess; + } + + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + } + + public Consumer getOnStop() { + return onStop; } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/BreakBlockAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerBreakBlockAction.java similarity index 87% rename from leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/BreakBlockAction.java rename to leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerBreakBlockAction.java index bf7d2037..a7d6b03b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/BreakBlockAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerBreakBlockAction.java @@ -7,11 +7,12 @@ import org.bukkit.block.Block; import org.bukkit.craftbukkit.block.CraftBlock; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.entity.bot.actions.CraftBreakBlockAction; -public class BreakBlockAction extends AbstractTimerAction { +public class ServerBreakBlockAction extends ServerTimerBotAction { - public BreakBlockAction() { - super("break", BreakBlockAction::new); + public ServerBreakBlockAction() { + super("break", ServerBreakBlockAction::new); } private BlockPos lastPos = null; @@ -72,4 +73,9 @@ public class BreakBlockAction extends AbstractTimerAction { return f; } + + @Override + public Object asCraft() { + return new CraftBreakBlockAction(this); + } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerDropAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerDropAction.java new file mode 100644 index 00000000..a2818e7e --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerDropAction.java @@ -0,0 +1,23 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.entity.bot.actions.CraftDropAction; + +public class ServerDropAction extends ServerTimerBotAction { + + public ServerDropAction() { + super("drop", ServerDropAction::new); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + bot.dropAll(false); + return true; + } + + @Override + public Object asCraft() { + return new CraftDropAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/FishAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerFishAction.java similarity index 84% rename from leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/FishAction.java rename to leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerFishAction.java index 8610825e..514e11b8 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/FishAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerFishAction.java @@ -7,11 +7,12 @@ import net.minecraft.world.item.FishingRodItem; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.entity.bot.actions.CraftFishAction; -public class FishAction extends AbstractTimerAction { +public class ServerFishAction extends ServerTimerBotAction { - public FishAction() { - super("fish", FishAction::new); + public ServerFishAction() { + super("fish", ServerFishAction::new); } private static final int CATCH_ENTITY_DELAY = 20; @@ -20,10 +21,9 @@ public class FishAction extends AbstractTimerAction { private int tickToNextFish = 0; @Override - public FishAction setInitialTickInterval(int initialTickInterval) { - super.setInitialTickInterval(1); + public void setDoIntervalTick(int initialTickInterval) { + super.setDoIntervalTick(1); this.initialFishInterval = initialTickInterval; - return this; } @Override @@ -72,4 +72,9 @@ public class FishAction extends AbstractTimerAction { return false; } + + @Override + public Object asCraft() { + return new CraftFishAction(this); + } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerJumpAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerJumpAction.java new file mode 100644 index 00000000..1930c1a7 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerJumpAction.java @@ -0,0 +1,27 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.entity.bot.actions.CraftJumpAction; + +public class ServerJumpAction extends ServerTimerBotAction { + + public ServerJumpAction() { + super("jump", ServerJumpAction::new); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + if (!bot.onGround()) { + return false; + } else { + bot.jumpFromGround(); + } + return true; + } + + @Override + public Object asCraft() { + return new CraftJumpAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerLookAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerLookAction.java new file mode 100644 index 00000000..59a4609a --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerLookAction.java @@ -0,0 +1,126 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import org.apache.commons.lang3.tuple.Pair; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftLookAction; + +import java.text.DecimalFormat; +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; + +public abstract class ServerLookAction> extends ServerBotAction { + + private static final Vector ZERO_VECTOR = new Vector(0, 0, 0); + + private Vector pos = ZERO_VECTOR; + private ServerPlayer target = null; + + private ServerLookAction(String name, CommandArgument argument, Supplier creator) { + super(name, argument, creator); + } + + @Override + @NotNull + public CompoundTag save(@NotNull CompoundTag nbt) { + super.save(nbt); + if (target != null) { + this.pos.setX(this.target.getX()); + this.pos.setY(this.target.getY()); + this.pos.setZ(this.target.getZ()); + } + nbt.putDouble("x", this.pos.getX()); + nbt.putDouble("y", this.pos.getY()); + nbt.putDouble("z", this.pos.getZ()); + return nbt; + } + + @Override + public void load(@NotNull CompoundTag nbt) { + super.load(nbt); + this.setPos( + new Vector( + nbt.getDouble("x").orElse(0.0), + nbt.getDouble("y").orElse(0.0), + nbt.getDouble("z").orElse(0.0) + ) + ); + } + + public void setPos(Vector pos) { + this.pos = pos; + } + + public Vector getPos() { + return this.pos; + } + + public void setTarget(ServerPlayer player) { + this.target = player; + } + + public ServerPlayer getTarget() { + return target; + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + if (target != null) { + bot.faceLocation(target.getBukkitEntity().getLocation()); + } else { + bot.look(pos.subtract(bot.getLocation().toVector()), false); + } + return true; + } + + public static class TO extends ServerLookAction { + public TO() { + super("look_to", CommandArgument.of(CommandArgumentType.STRING), TO::new); + this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(Arrays.asList(player.getServer().getPlayerNames()), "") : Pair.of(List.of("0"), "")); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + String name = result.readString(player.getScoreboardName()); + ServerPlayer player1 = player.getServer().getPlayerList().getPlayerByName(name); + if (player1 == null) { + throw new IllegalArgumentException("No such player"); + } else { + this.setTarget(player1); + } + } + } + + public static class ON extends ServerLookAction { + private static final DecimalFormat DF = new DecimalFormat("0.0"); + + public ON() { + super("look_on", CommandArgument.of(CommandArgumentType.DOUBLE, CommandArgumentType.BOOLEAN, CommandArgumentType.BOOLEAN), ON::new); + this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getX())), "") : Pair.of(List.of("0"), "")); + this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getY())), "") : Pair.of(List.of("0"), "")); + this.setSuggestion(2, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getZ())), "") : Pair.of(List.of("0"), "")); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + Vector vector = result.readVector(); + if (vector == null) { + throw new IllegalArgumentException("Invalid vector"); + } else { + this.setPos(vector); + } + } + } + + @Override + public Object asCraft() { + return new CraftLookAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerMoveAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerMoveAction.java new file mode 100644 index 00000000..c194547b --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerMoveAction.java @@ -0,0 +1,71 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.server.level.ServerPlayer; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.action.MoveAction.MoveDirection; +import org.leavesmc.leaves.entity.bot.actions.CraftMoveAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +import java.util.Arrays; +import java.util.List; + +public class ServerMoveAction extends ServerStateBotAction { + private static final Pair, String> suggestions = Pair.of( + Arrays.stream(MoveDirection.values()).map((it) -> it.name).toList(), + "" + ); + private MoveDirection direction = MoveDirection.FORWARD; + + public ServerMoveAction() { + super("move", CommandArgument.of(CommandArgumentType.ofEnum(MoveDirection.class)), ServerMoveAction::new); + this.setSuggestion(0, (sender, arg) -> suggestions); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + this.direction = result.read(MoveDirection.class); + if (direction == null) { + throw new IllegalArgumentException("Invalid direction"); + } + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + switch (direction) { + case FORWARD, BACKWARD -> bot.zza = 0.0f; + case LEFT, RIGHT -> bot.xxa = 0.0f; + } + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + boolean isSneaking = bot.isShiftKeyDown(); + float velocity = isSneaking ? 0.3f : 1.0f; + switch (direction) { + case FORWARD -> bot.zza = velocity; + case BACKWARD -> bot.zza = -velocity; + case LEFT -> bot.xxa = velocity; + case RIGHT -> bot.xxa = -velocity; + } + return true; + } + + public MoveDirection getDirection() { + return direction; + } + + public void setDirection(MoveDirection direction) { + this.direction = direction; + } + + @Override + public Object asCraft() { + return new CraftMoveAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/RotationAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerRotationAction.java similarity index 55% rename from leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/RotationAction.java rename to leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerRotationAction.java index e0833dff..a545dc1e 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/RotationAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerRotationAction.java @@ -4,46 +4,53 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.command.CommandArgumentResult; import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftRotationAction; import java.text.DecimalFormat; import java.util.List; +import java.util.Objects; -public class RotationAction extends AbstractBotAction { +public class ServerRotationAction extends ServerBotAction { private static final DecimalFormat DF = new DecimalFormat("0.00"); - public RotationAction() { - super("rotation", CommandArgument.of(CommandArgumentType.FLOAT, CommandArgumentType.FLOAT), RotationAction::new); + public ServerRotationAction() { + super("rotation", CommandArgument.of(CommandArgumentType.FLOAT, CommandArgumentType.FLOAT), ServerRotationAction::new); this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getYRot())), "[yaw]") : Pair.of(List.of("0"), "")); - this.setSuggestion(0, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getXRot())), "[pitch]") : Pair.of(List.of("0"), "")); + this.setSuggestion(1, (sender, arg) -> sender instanceof ServerPlayer player ? Pair.of(List.of(DF.format(player.getXRot())), "[pitch]") : Pair.of(List.of("0"), "")); } - private float yaw; - private float pitch; + private float yaw = 0.0f; + private float pitch = 0.0f; @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - if (player == null) { - return; + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + try { + this.yaw = result.readFloat(Objects.requireNonNull(player).getYRot()); + this.pitch = result.readFloat(player.getXRot()); + } catch (Exception e) { + throw new IllegalArgumentException("No valid rotation specified", e); } - - this.setYaw(result.readFloat(player.getYRot())).setPitch(result.readFloat(player.getXRot())).setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1); } - public RotationAction setYaw(float yaw) { + public void setYaw(float yaw) { this.yaw = yaw; - return this; } - public RotationAction setPitch(float pitch) { + public void setPitch(float pitch) { this.pitch = pitch; - return this; + } + + public float getYaw() { + return this.yaw; + } + + public float getPitch() { + return this.pitch; } @Override @@ -58,7 +65,8 @@ public class RotationAction extends AbstractBotAction { @Override public void load(@NotNull CompoundTag nbt) { super.load(nbt); - this.setYaw(nbt.getFloat("yaw").orElseThrow()).setPitch(nbt.getFloat("pitch").orElseThrow()); + this.setYaw(nbt.getFloat("yaw").orElseThrow()); + this.setPitch(nbt.getFloat("pitch").orElseThrow()); } @Override @@ -66,4 +74,9 @@ public class RotationAction extends AbstractBotAction { bot.setRot(yaw, pitch); return true; } + + @Override + public Object asCraft() { + return new CraftRotationAction(this); + } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerSneakAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerSneakAction.java new file mode 100644 index 00000000..104cb194 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerSneakAction.java @@ -0,0 +1,35 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.entity.bot.actions.CraftSneakAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +public class ServerSneakAction extends ServerStateBotAction { + + public ServerSneakAction() { + super("sneak", CommandArgument.EMPTY, ServerSneakAction::new); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + if (bot.isShiftKeyDown()) { + return false; + } + + bot.setShiftKeyDown(true); + return true; + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.setShiftKeyDown(false); + } + + @Override + public Object asCraft() { + return new CraftSneakAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerStateBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerStateBotAction.java new file mode 100644 index 00000000..12452a22 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerStateBotAction.java @@ -0,0 +1,12 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import org.leavesmc.leaves.command.CommandArgument; + +import java.util.function.Supplier; + +public abstract class ServerStateBotAction> extends ServerBotAction { + public ServerStateBotAction(String name, CommandArgument argument, Supplier creator) { + super(name, argument, creator); + this.setDoNumber(-1); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerSwimAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerSwimAction.java new file mode 100644 index 00000000..50576fe6 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerSwimAction.java @@ -0,0 +1,27 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.entity.bot.actions.CraftSwimAction; + +public class ServerSwimAction extends ServerStateBotAction { + + public ServerSwimAction() { + super("swim", CommandArgument.EMPTY, ServerSwimAction::new); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + if (bot.isInWater()) { + bot.addDeltaMovement(new Vec3(0, 0.03, 0)); + } + return true; + } + + @Override + public Object asCraft() { + return new CraftSwimAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/AbstractTimerAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerTimerBotAction.java similarity index 60% rename from leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/AbstractTimerAction.java rename to leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerTimerBotAction.java index 7859594d..63d172ca 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/AbstractTimerAction.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerTimerBotAction.java @@ -3,8 +3,6 @@ package org.leavesmc.leaves.bot.agent.actions; import net.minecraft.server.level.ServerPlayer; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.command.CommandArgumentResult; import org.leavesmc.leaves.command.CommandArgumentType; @@ -13,13 +11,13 @@ import java.util.Collections; import java.util.List; import java.util.function.Supplier; -public abstract class AbstractTimerAction> extends AbstractBotAction { +public abstract class ServerTimerBotAction> extends ServerBotAction { - public AbstractTimerAction(String name, Supplier creator) { + public ServerTimerBotAction(String name, Supplier creator) { this(name, CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), creator); } - public AbstractTimerAction(String name, CommandArgument argument, Supplier creator) { + public ServerTimerBotAction(String name, CommandArgument argument, Supplier creator) { super(name, argument, creator); this.setSuggestion(0, Pair.of(Collections.singletonList("0"), "[TickDelay]")); this.setSuggestion(1, Pair.of(Collections.singletonList("20"), "[TickInterval]")); @@ -27,7 +25,9 @@ public abstract class AbstractTimerAction> exte } @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - this.setInitialTickDelay(result.readInt(0)).setInitialTickInterval(result.readInt(20)).setInitialNumber(result.readInt(1)); + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + this.setStartDelayTick(result.readInt(0)); + this.setDoIntervalTick(result.readInt(20)); + this.setDoNumber(result.readInt(1)); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemAction.java new file mode 100644 index 00000000..b8838f4d --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemAction.java @@ -0,0 +1,110 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +import java.util.Collections; + +public class ServerUseItemAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemAction() { + super("use", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + boolean result = execute(bot); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + @Override + @NotNull + public CompoundTag save(@NotNull CompoundTag nbt) { + super.save(nbt); + nbt.putInt("useTick", this.useTick); + nbt.putInt("tickToRelease", this.tickToRelease); + return nbt; + } + + @Override + public void load(@NotNull CompoundTag nbt) { + super.load(nbt); + this.useTick = nbt.getInt("useTick").orElseThrow(); + this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow(); + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public static boolean execute(@NotNull ServerBot bot) { + if (bot.isUsingItem()) { + return false; + } + + boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND).consumesAction(); + if (flag) { + bot.swing(InteractionHand.MAIN_HAND); + bot.updateItemInHand(InteractionHand.MAIN_HAND); + } + return flag; + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemAutoAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemAutoAction.java new file mode 100644 index 00000000..a65e6f29 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemAutoAction.java @@ -0,0 +1,109 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.BlockHitResult; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemAutoAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +import java.util.Collections; + +public class ServerUseItemAutoAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemAutoAction() { + super("use_auto", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemAutoAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + boolean result = execute(bot); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public boolean execute(@NotNull ServerBot bot) { + if (bot.isUsingItem()) { + return false; + } + + Entity entity = bot.getTargetEntity(3, null); + BlockHitResult blockHitResult = (BlockHitResult) bot.getRayTrace(5, ClipContext.Fluid.NONE); + boolean mainSuccess, useTo = entity != null, useOn = !bot.level().getBlockState(blockHitResult.getBlockPos()).isAir(); + if (useTo) { + mainSuccess = ServerUseItemToAction.execute(bot, entity) || ServerUseItemAction.execute(bot); + } else if (useOn) { + mainSuccess = ServerUseItemOnAction.execute(bot, blockHitResult) || ServerUseItemAction.execute(bot); + } else { + mainSuccess = ServerUseItemAction.execute(bot); + } + if (mainSuccess) { + return true; + } + if (useTo) { + return ServerUseItemToOffhandAction.execute(bot, entity) || ServerUseItemOffhandAction.execute(bot); + } else if (useOn) { + return ServerUseItemOnOffhandAction.execute(bot, blockHitResult) || ServerUseItemOffhandAction.execute(bot); + } else { + return ServerUseItemOffhandAction.execute(bot); + } + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemAutoAction(this); + } +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOffhandAction.java new file mode 100644 index 00000000..52d7fd10 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOffhandAction.java @@ -0,0 +1,110 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemOffhandAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +import java.util.Collections; + +public class ServerUseItemOffhandAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemOffhandAction() { + super("use_offhand", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemOffhandAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + boolean result = execute(bot); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + @Override + @NotNull + public CompoundTag save(@NotNull CompoundTag nbt) { + super.save(nbt); + nbt.putInt("useTick", this.useTick); + nbt.putInt("tickToRelease", this.tickToRelease); + return nbt; + } + + @Override + public void load(@NotNull CompoundTag nbt) { + super.load(nbt); + this.useTick = nbt.getInt("useTick").orElseThrow(); + this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow(); + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public static boolean execute(@NotNull ServerBot bot) { + if (bot.isUsingItem()) { + return false; + } + + boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND).consumesAction(); + if (flag) { + bot.swing(InteractionHand.OFF_HAND); + bot.updateItemInHand(InteractionHand.OFF_HAND); + } + return flag; + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemOffhandAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOnAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOnAction.java new file mode 100644 index 00000000..330619a9 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOnAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.TrappedChestBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import org.apache.commons.lang3.tuple.Pair; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemOnAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; +import org.leavesmc.leaves.plugin.MinecraftInternalPlugin; + +import java.util.Collections; + +public class ServerUseItemOnAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemOnAction() { + super("use_on", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemOnAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + HitResult hitResult = bot.getRayTrace(5, ClipContext.Fluid.NONE); + boolean result = execute(bot, hitResult); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + @Override + @NotNull + public CompoundTag save(@NotNull CompoundTag nbt) { + super.save(nbt); + nbt.putInt("useTick", this.useTick); + nbt.putInt("tickToRelease", this.tickToRelease); + return nbt; + } + + @Override + public void load(@NotNull CompoundTag nbt) { + super.load(nbt); + this.useTick = nbt.getInt("useTick").orElseThrow(); + this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow(); + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public static boolean execute(@NotNull ServerBot bot, HitResult result) { + if (!(result instanceof BlockHitResult blockHitResult)) { + return false; + } + BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos()); + if (state.isAir()) { + return false; + } else { + bot.swing(InteractionHand.MAIN_HAND); + if (state.getBlock() == Blocks.TRAPPED_CHEST) { + BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos()); + if (entity instanceof TrappedChestBlockEntity chestBlockEntity) { + chestBlockEntity.startOpen(bot); + Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1); + return true; + } else { + return false; + } + + } else { + bot.updateItemInHand(InteractionHand.MAIN_HAND); + return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, blockHitResult).consumesAction(); + } + } + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemOnAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOnOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOnOffhandAction.java new file mode 100644 index 00000000..d160f852 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemOnOffhandAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.TrappedChestBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import org.apache.commons.lang3.tuple.Pair; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemOnOffhandAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; +import org.leavesmc.leaves.plugin.MinecraftInternalPlugin; + +import java.util.Collections; + +public class ServerUseItemOnOffhandAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemOnOffhandAction() { + super("use_on_offhand", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemOnOffhandAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + HitResult hitResult = bot.getRayTrace(5, ClipContext.Fluid.NONE); + boolean result = execute(bot, hitResult); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + @Override + @NotNull + public CompoundTag save(@NotNull CompoundTag nbt) { + super.save(nbt); + nbt.putInt("useTick", this.useTick); + nbt.putInt("tickToRelease", this.tickToRelease); + return nbt; + } + + @Override + public void load(@NotNull CompoundTag nbt) { + super.load(nbt); + this.useTick = nbt.getInt("useTick").orElseThrow(); + this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow(); + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public static boolean execute(ServerBot bot, HitResult result) { + if (!(result instanceof BlockHitResult blockHitResult)) { + return false; + } + + BlockState state = bot.level().getBlockState(blockHitResult.getBlockPos()); + if (state.isAir()) { + return false; + } else { + bot.swing(InteractionHand.OFF_HAND); + if (state.getBlock() == Blocks.TRAPPED_CHEST) { + BlockEntity entity = bot.level().getBlockEntity(blockHitResult.getBlockPos()); + if (entity instanceof TrappedChestBlockEntity chestBlockEntity) { + chestBlockEntity.startOpen(bot); + Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1); + return true; + } else { + return false; + } + } else { + bot.updateItemInHand(InteractionHand.OFF_HAND); + return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, blockHitResult).consumesAction(); + } + } + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemOnOffhandAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemToAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemToAction.java new file mode 100644 index 00000000..62cf461c --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemToAction.java @@ -0,0 +1,95 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemToAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +import java.util.Collections; + +public class ServerUseItemToAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemToAction() { + super("use_to", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemToAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + Entity entity = bot.getTargetEntity(3, null); + boolean result = execute(bot, entity); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public static boolean execute(ServerBot bot, Entity entity) { + if (entity == null) { + return false; + } + + boolean flag = bot.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction(); + if (flag) { + bot.swing(InteractionHand.MAIN_HAND); + bot.updateItemInHand(InteractionHand.MAIN_HAND); + } + return flag; + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemToAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemToOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemToOffhandAction.java new file mode 100644 index 00000000..69424c14 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ServerUseItemToOffhandAction.java @@ -0,0 +1,95 @@ +package org.leavesmc.leaves.bot.agent.actions; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentResult; +import org.leavesmc.leaves.command.CommandArgumentType; +import org.leavesmc.leaves.entity.bot.actions.CraftUseItemToOffhandAction; +import org.leavesmc.leaves.event.bot.BotActionStopEvent; + +import java.util.Collections; + +public class ServerUseItemToOffhandAction extends ServerTimerBotAction { + private int useTick = -1; + private int tickToRelease = -1; + + public ServerUseItemToOffhandAction() { + super("use_to_offhand", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ServerUseItemToOffhandAction::new); + this.setSuggestion(3, Pair.of(Collections.singletonList("-1"), "[UseTick]")); + } + + @Override + public void init() { + super.init(); + syncTickToRelease(); + } + + @Override + public void loadCommand(ServerPlayer player, @NotNull CommandArgumentResult result) { + super.loadCommand(player, result); + this.useTick = result.readInt(-1); + } + + @Override + public boolean doTick(@NotNull ServerBot bot) { + tickToRelease--; + if (tickToRelease >= 0) { + Entity entity = bot.getTargetEntity(3, null); + boolean result = execute(bot, entity); + if (useTick >= 0) { + return false; + } else { + return result; + } + } else { + syncTickToRelease(); + bot.releaseUsingItem(); + return true; + } + } + + private void syncTickToRelease() { + if (this.useTick >= 0) { + this.tickToRelease = this.useTick; + } else { + this.tickToRelease = Integer.MAX_VALUE; + } + } + + public int getUseTick() { + return useTick; + } + + public void setUseTick(int useTick) { + this.useTick = useTick; + } + + public static boolean execute(ServerBot bot, Entity entity) { + if (entity == null) { + return false; + } + + boolean flag = bot.interactOn(entity, InteractionHand.OFF_HAND).consumesAction(); + if (flag) { + bot.swing(InteractionHand.OFF_HAND); + bot.updateItemInHand(InteractionHand.OFF_HAND); + } + return flag; + } + + @Override + public void stop(@NotNull ServerBot bot, BotActionStopEvent.Reason reason) { + super.stop(bot, reason); + bot.completeUsingItem(); + } + + @Override + public Object asCraft() { + return new CraftUseItemToOffhandAction(this); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ShootAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ShootAction.java deleted file mode 100644 index 1a0dbc72..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/ShootAction.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.item.Items; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.command.CommandArgument; -import org.leavesmc.leaves.command.CommandArgumentResult; -import org.leavesmc.leaves.command.CommandArgumentType; - -import java.util.Collections; - -public class ShootAction extends AbstractTimerAction { - - private int drawingTick; - private int tickToRelease = -1; - - public ShootAction() { - super("shoot", CommandArgument.of(CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER, CommandArgumentType.INTEGER), ShootAction::new); - this.setSuggestion(3, Pair.of(Collections.singletonList("20"), "[DrawingTick]")); - } - - @Override - public void init() { - super.init(); - tickToRelease = drawingTick; - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - if (!bot.getItemInHand(InteractionHand.MAIN_HAND).is(Items.BOW)) { - return false; - } - tickToRelease--; - if (tickToRelease >= 0) { - bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND).consumesAction(); - bot.updateItemInHand(InteractionHand.MAIN_HAND); - return false; - } else { - bot.releaseUsingItem(); - tickToRelease = drawingTick; - return true; - } - } - - @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - super.loadCommand(player, result); - this.setDrawingTick(result.readInt(20)); - } - - @Override - @NotNull - public CompoundTag save(@NotNull CompoundTag nbt) { - super.save(nbt); - nbt.putInt("drawingTick", this.drawingTick); - nbt.putInt("tickToRelease", this.tickToRelease); - return nbt; - } - - @Override - public void load(@NotNull CompoundTag nbt) { - super.load(nbt); - this.drawingTick = nbt.getInt("drawingTick").orElseThrow(); - this.tickToRelease = nbt.getInt("tickToRelease").orElseThrow(); - } - - public int getDrawingTick() { - return drawingTick; - } - - public ShootAction setDrawingTick(int drawingTick) { - this.drawingTick = drawingTick; - return this; - } -} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/SneakAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/SneakAction.java deleted file mode 100644 index 1218e556..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/SneakAction.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.server.level.ServerPlayer; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.command.CommandArgument; -import org.leavesmc.leaves.command.CommandArgumentResult; - -public class SneakAction extends AbstractBotAction { - - public SneakAction() { - super("sneak", CommandArgument.EMPTY, SneakAction::new); - } - - @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(1); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - bot.setShiftKeyDown(!bot.isShiftKeyDown()); - return true; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/SwimAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/SwimAction.java deleted file mode 100644 index 1c29a9ef..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/SwimAction.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.command.CommandArgument; -import org.leavesmc.leaves.command.CommandArgumentResult; - -public class SwimAction extends AbstractBotAction { - - public SwimAction() { - super("swim", CommandArgument.EMPTY, SwimAction::new); - } - - @Override - public void loadCommand(@Nullable ServerPlayer player, @NotNull CommandArgumentResult result) { - this.setInitialTickDelay(0).setInitialTickInterval(1).setInitialNumber(-1); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - if (bot.isInWater()) { - bot.addDeltaMovement(new Vec3(0, 0.03, 0)); - } - return true; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemAction.java deleted file mode 100644 index c511ed17..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemAction.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.world.InteractionHand; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; - -public class UseItemAction extends AbstractTimerAction { - - public UseItemAction() { - super("use", UseItemAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - if (bot.isUsingItem()) { - return false; - } - - boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND).consumesAction(); - if (flag) { - bot.swing(InteractionHand.MAIN_HAND); - bot.updateItemInHand(InteractionHand.MAIN_HAND); - } - return flag; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOffHandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOffHandAction.java deleted file mode 100644 index 26d7286f..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOffHandAction.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.world.InteractionHand; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; - -public class UseItemOffHandAction extends AbstractTimerAction { - - public UseItemOffHandAction() { - super("use_offhand", UseItemOffHandAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - if (bot.isUsingItem()) { - return false; - } - - boolean flag = bot.gameMode.useItem(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND).consumesAction(); - if (flag) { - bot.swing(InteractionHand.OFF_HAND); - bot.updateItemInHand(InteractionHand.OFF_HAND); - } - return flag; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOnAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOnAction.java deleted file mode 100644 index 232d0abe..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOnAction.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.world.InteractionHand; -import net.minecraft.world.level.ClipContext; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.TrappedChestBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.plugin.MinecraftInternalPlugin; - -public class UseItemOnAction extends AbstractTimerAction { - - public UseItemOnAction() { - super("use_on", UseItemOnAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE); - if (result instanceof BlockHitResult blockHitResult) { - BlockState state = bot.serverLevel().getBlockState(blockHitResult.getBlockPos()); - if (state.isAir()) { - return false; - } - bot.swing(InteractionHand.MAIN_HAND); - if (state.getBlock() == Blocks.TRAPPED_CHEST) { - BlockEntity entity = bot.serverLevel().getBlockEntity(blockHitResult.getBlockPos()); - if (entity instanceof TrappedChestBlockEntity chestBlockEntity) { - chestBlockEntity.startOpen(bot); - Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1); - return true; - } - } else { - bot.updateItemInHand(InteractionHand.MAIN_HAND); - return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.MAIN_HAND), InteractionHand.MAIN_HAND, (BlockHitResult) result).consumesAction(); - } - } - return false; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOnOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOnOffhandAction.java deleted file mode 100644 index 3616802c..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemOnOffhandAction.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.world.InteractionHand; -import net.minecraft.world.level.ClipContext; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.TrappedChestBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; -import org.bukkit.Bukkit; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.plugin.MinecraftInternalPlugin; - -public class UseItemOnOffhandAction extends AbstractTimerAction { - - public UseItemOnOffhandAction() { - super("use_on_offhand", UseItemOnOffhandAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - HitResult result = bot.getRayTrace(5, ClipContext.Fluid.NONE); - if (result instanceof BlockHitResult blockHitResult) { - BlockState state = bot.serverLevel().getBlockState(blockHitResult.getBlockPos()); - if (state.isAir()) { - return false; - } - bot.swing(InteractionHand.OFF_HAND); - if (state.getBlock() == Blocks.TRAPPED_CHEST) { - BlockEntity entity = bot.serverLevel().getBlockEntity(blockHitResult.getBlockPos()); - if (entity instanceof TrappedChestBlockEntity chestBlockEntity) { - chestBlockEntity.startOpen(bot); - Bukkit.getScheduler().runTaskLater(MinecraftInternalPlugin.INSTANCE, () -> chestBlockEntity.stopOpen(bot), 1); - return true; - } - } else { - bot.updateItemInHand(InteractionHand.OFF_HAND); - return bot.gameMode.useItemOn(bot, bot.level(), bot.getItemInHand(InteractionHand.OFF_HAND), InteractionHand.OFF_HAND, (BlockHitResult) result).consumesAction(); - } - } - return false; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemToAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemToAction.java deleted file mode 100644 index 05be3dd5..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemToAction.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; - -public class UseItemToAction extends AbstractTimerAction { - - public UseItemToAction() { - super("use_to", UseItemToAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - Entity entity = bot.getTargetEntity(3, null); - if (entity != null) { - boolean flag = bot.interactOn(entity, InteractionHand.MAIN_HAND).consumesAction(); - if (flag) { - bot.swing(InteractionHand.MAIN_HAND); - bot.updateItemInHand(InteractionHand.MAIN_HAND); - } - return flag; - } - return false; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemToOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemToOffhandAction.java deleted file mode 100644 index f8334858..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/actions/UseItemToOffhandAction.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.leavesmc.leaves.bot.agent.actions; - -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.bot.ServerBot; - -public class UseItemToOffhandAction extends AbstractTimerAction { - - public UseItemToOffhandAction() { - super("use_to_offhand", UseItemToOffhandAction::new); - } - - @Override - public boolean doTick(@NotNull ServerBot bot) { - Entity entity = bot.getTargetEntity(3, null); - if (entity != null) { - boolean flag = bot.interactOn(entity, InteractionHand.OFF_HAND).consumesAction(); - if (flag) { - bot.swing(InteractionHand.OFF_HAND); - bot.updateItemInHand(InteractionHand.OFF_HAND); - } - return flag; - } - return false; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java index 3e42b990..8ef871cc 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java @@ -17,7 +17,7 @@ public class AlwaysSendDataConfig extends AbstractBotConfig { public AlwaysSendDataConfig() { super(NAME, CommandArgument.of(CommandArgumentType.BOOLEAN).setSuggestion(0, List.of("true", "false"))); - this.value = LeavesConfig.modify.fakeplayer.canSendDataAlways; + this.value = LeavesConfig.modify.fakeplayer.inGame.canSendDataAlways; } @Override @@ -40,6 +40,6 @@ public class AlwaysSendDataConfig extends AbstractBotConfig { @Override public void load(@NotNull CompoundTag nbt) { - this.setValue(nbt.getBoolean(NAME).orElseThrow()); + this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.canSendDataAlways)); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/LocatorBarConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/LocatorBarConfig.java new file mode 100644 index 00000000..1b0a02f0 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/LocatorBarConfig.java @@ -0,0 +1,51 @@ +package org.leavesmc.leaves.bot.agent.configs; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.waypoints.ServerWaypointManager; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.bot.agent.AbstractBotConfig; +import org.leavesmc.leaves.command.CommandArgument; +import org.leavesmc.leaves.command.CommandArgumentType; + +import java.util.List; + +public class LocatorBarConfig extends AbstractBotConfig { + + public static final String NAME = "enable_locator_bar"; + + private boolean value; + + public LocatorBarConfig() { + super(NAME, CommandArgument.of(CommandArgumentType.BOOLEAN).setSuggestion(0, List.of("true", "false"))); + this.value = LeavesConfig.modify.fakeplayer.inGame.enableLocatorBar; + } + + @Override + public Boolean getValue() { + return value; + } + + @Override + public void setValue(Boolean value) throws IllegalArgumentException { + this.value = value; + ServerWaypointManager manager = this.bot.level().getWaypointManager(); + if (value) { + manager.trackWaypoint(this.bot); + } else { + manager.untrackWaypoint(this.bot); + } + } + + @Override + public @NotNull CompoundTag save(@NotNull CompoundTag nbt) { + super.save(nbt); + nbt.putBoolean(NAME, this.getValue()); + return nbt; + } + + @Override + public void load(@NotNull CompoundTag nbt) { + this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.enableLocatorBar)); + } +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SimulationDistanceConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SimulationDistanceConfig.java index 4d7d72b1..56751f72 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SimulationDistanceConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SimulationDistanceConfig.java @@ -3,6 +3,7 @@ package org.leavesmc.leaves.bot.agent.configs; import net.minecraft.nbt.CompoundTag; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesConfig; import org.leavesmc.leaves.bot.agent.AbstractBotConfig; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.command.CommandArgumentType; @@ -40,6 +41,6 @@ public class SimulationDistanceConfig extends AbstractBotConfig { @Override public void load(@NotNull CompoundTag nbt) { - this.setValue(nbt.getInt(NAME).orElseThrow()); + this.setValue(nbt.getIntOr(NAME, LeavesConfig.modify.fakeplayer.inGame.getSimulationDistance(this.bot))); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SkipSleepConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SkipSleepConfig.java index 99b6e682..cf4b0610 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SkipSleepConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SkipSleepConfig.java @@ -2,6 +2,7 @@ package org.leavesmc.leaves.bot.agent.configs; import net.minecraft.nbt.CompoundTag; import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesConfig; import org.leavesmc.leaves.bot.agent.AbstractBotConfig; import org.leavesmc.leaves.command.CommandArgument; import org.leavesmc.leaves.command.CommandArgumentType; @@ -35,6 +36,6 @@ public class SkipSleepConfig extends AbstractBotConfig { @Override public void load(@NotNull CompoundTag nbt) { - this.setValue(nbt.getBoolean(NAME).orElseThrow()); + this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.canSkipSleep)); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java index 6d9840ea..13be5fee 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java @@ -17,7 +17,7 @@ public class SpawnPhantomConfig extends AbstractBotConfig { public SpawnPhantomConfig() { super(NAME, CommandArgument.of(CommandArgumentType.BOOLEAN).setSuggestion(0, List.of("true", "false"))); - this.value = LeavesConfig.modify.fakeplayer.canSpawnPhantom; + this.value = LeavesConfig.modify.fakeplayer.inGame.canSpawnPhantom; } @Override @@ -47,6 +47,6 @@ public class SpawnPhantomConfig extends AbstractBotConfig { @Override public void load(@NotNull CompoundTag nbt) { - this.setValue(nbt.getBoolean(NAME).orElseThrow()); + this.setValue(nbt.getBooleanOr(NAME, LeavesConfig.modify.fakeplayer.inGame.canSpawnPhantom)); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/TickTypeConfig.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/TickTypeConfig.java index 66af8e40..0615a439 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/TickTypeConfig.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/agent/configs/TickTypeConfig.java @@ -19,7 +19,7 @@ public class TickTypeConfig extends AbstractBotConfig { public TickTypeConfig() { super(NAME, CommandArgument.of(TICK_TYPE_ARGUMENT).setSuggestion(0, List.of("network", "entity_list"))); - this.value = LeavesConfig.modify.fakeplayer.tickType; + this.value = LeavesConfig.modify.fakeplayer.inGame.tickType; } @Override @@ -42,6 +42,6 @@ public class TickTypeConfig extends AbstractBotConfig { @Override public void load(@NotNull CompoundTag nbt) { - this.setValue(TICK_TYPE_ARGUMENT.parse(nbt.getString(NAME).orElseThrow())); + this.setValue(TICK_TYPE_ARGUMENT.parse(nbt.getStringOr(NAME, LeavesConfig.modify.fakeplayer.inGame.tickType.name()))); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotActionCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotActionCommand.java index 29d13645..f6be953b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotActionCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotActionCommand.java @@ -10,9 +10,8 @@ import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.LeavesConfig; import org.leavesmc.leaves.bot.BotList; import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; import org.leavesmc.leaves.bot.agent.Actions; -import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction; +import org.leavesmc.leaves.bot.agent.actions.*; import org.leavesmc.leaves.command.LeavesSubcommand; import org.leavesmc.leaves.command.LeavesSuggestionBuilder; import org.leavesmc.leaves.event.bot.BotActionStopEvent; @@ -21,7 +20,6 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import static net.kyori.adventure.text.Component.text; @@ -53,7 +51,7 @@ public class BotActionCommand implements LeavesSubcommand { } private void executeStart(ServerBot bot, CommandSender sender, String[] args) { - AbstractBotAction action = Actions.getForName(args[2]); + ServerBotAction action = Actions.getForName(args[2]); if (action == null) { sender.sendMessage(text("Invalid action", NamedTextColor.RED)); return; @@ -67,23 +65,15 @@ public class BotActionCommand implements LeavesSubcommand { } String[] realArgs = Arrays.copyOfRange(args, 3, args.length); - AbstractBotAction newAction; + ServerBotAction newAction; try { - if (action instanceof CraftCustomBotAction customBotAction) { - newAction = customBotAction.createCraft(player, realArgs); - } else { - newAction = action.create(); - newAction.loadCommand(player.getHandle(), action.getArgument().parse(0, realArgs)); - } + newAction = action.create(); + newAction.loadCommand(player.getHandle(), action.getArgument().parse(0, realArgs)); } catch (IllegalArgumentException e) { sender.sendMessage(text("Action create error, please check your arguments, " + e.getMessage(), NamedTextColor.RED)); return; } - if (newAction == null) { - return; - } - if (bot.addBotAction(newAction, sender)) { sender.sendMessage("Action " + action.getName() + " has been issued to " + bot.getName().getString()); } @@ -97,15 +87,16 @@ public class BotActionCommand implements LeavesSubcommand { String index = args[2]; if (index.equals("all")) { - Set> forRemoval = new HashSet<>(); + Set> forRemoval = new HashSet<>(); for (int i = 0; i < bot.getBotActions().size(); i++) { - AbstractBotAction action = bot.getBotActions().get(i); + ServerBotAction action = bot.getBotActions().get(i); BotActionStopEvent event = new BotActionStopEvent( bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender ); event.callEvent(); if (!event.isCancelled()) { forRemoval.add(action); + action.stop(bot, BotActionStopEvent.Reason.COMMAND); } } bot.getBotActions().removeAll(forRemoval); @@ -119,12 +110,13 @@ public class BotActionCommand implements LeavesSubcommand { return; } - AbstractBotAction action = bot.getBotActions().get(i); + ServerBotAction action = bot.getBotActions().get(i); BotActionStopEvent event = new BotActionStopEvent( bot.getBukkitEntity(), action.getName(), action.getUUID(), BotActionStopEvent.Reason.COMMAND, sender ); event.callEvent(); if (!event.isCancelled()) { + action.stop(bot, BotActionStopEvent.Reason.COMMAND); bot.getBotActions().remove(i); sender.sendMessage(bot.getScoreboardName() + "'s " + action.getName() + " stopped."); @@ -158,7 +150,7 @@ public class BotActionCommand implements LeavesSubcommand { } } case 4, 5, 6, 7 -> { - AbstractBotAction action = Actions.getForName(args[2]); + ServerBotAction action = Actions.getForName(args[2]); if (action == null) { return; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotListCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotListCommand.java index 4d92cfcb..40088a0f 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotListCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bot/subcommands/BotListCommand.java @@ -12,7 +12,7 @@ import org.leavesmc.leaves.bot.BotList; import org.leavesmc.leaves.bot.ServerBot; import org.leavesmc.leaves.command.LeavesSubcommand; import org.leavesmc.leaves.command.LeavesSuggestionBuilder; -import org.leavesmc.leaves.entity.Bot; +import org.leavesmc.leaves.entity.bot.Bot; import java.util.ArrayList; import java.util.HashMap; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java b/leaves-server/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java index 0c32c205..e549e687 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java @@ -1,6 +1,8 @@ package org.leavesmc.leaves.bytebuf; import com.google.gson.JsonElement; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.JsonOps; import io.netty.buffer.ByteBuf; import net.minecraft.core.RegistryAccess; import net.minecraft.network.FriendlyByteBuf; @@ -226,7 +228,7 @@ public class WrappedBytebuf implements Bytebuf { @Override public Bytebuf writeComponentJson(JsonElement json) { - Component component = Component.Serializer.fromJson(json, RegistryAccess.EMPTY); + Component component = ComponentSerialization.CODEC.decode(JsonOps.INSTANCE, json).mapOrElse(Pair::getFirst, v -> null); if (component == null) { throw new IllegalArgumentException("Null can not be serialize to Minecraft chat component"); } @@ -236,7 +238,7 @@ public class WrappedBytebuf implements Bytebuf { @Override public JsonElement readComponentJson() { - return Component.Serializer.serialize(ComponentSerialization.STREAM_CODEC.decode(new RegistryFriendlyByteBuf(buf, RegistryAccess.EMPTY)), RegistryAccess.EMPTY); + return ComponentSerialization.CODEC.encodeStart(JsonOps.INSTANCE, ComponentSerialization.STREAM_CODEC.decode(new RegistryFriendlyByteBuf(buf, RegistryAccess.EMPTY))).getOrThrow(); } @Override diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java b/leaves-server/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java index 3764121a..92897be2 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/command/CommandArgumentResult.java @@ -54,6 +54,13 @@ public class CommandArgumentResult { return new Vector(pos[0], pos[1], pos[2]); } + public Object readObject() { + if (result.isEmpty()) { + return null; + } + return result.removeFirst(); + } + public T read(Class tClass, T def) { return Objects.requireNonNullElse(read(tClass), def); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/command/subcommands/ReportCommand.java b/leaves-server/src/main/java/org/leavesmc/leaves/command/subcommands/ReportCommand.java index 510474bb..924fa03b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/command/subcommands/ReportCommand.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/command/subcommands/ReportCommand.java @@ -56,8 +56,11 @@ public class ReportCommand implements LeavesSubcommand { if (provider instanceof SpigotPluginProvider) { spigotPlugins.put(configuration.getDisplayName(), provider); } else if (provider instanceof PaperPluginParent.PaperServerPluginProvider) { - if (provider.getMeta() instanceof LeavesPluginMeta) leavesPlugins.put(configuration.getDisplayName(), provider); - else paperPlugins.put(configuration.getDisplayName(), provider); + if (provider.getMeta() instanceof LeavesPluginMeta) { + leavesPlugins.put(configuration.getDisplayName(), provider); + } else { + paperPlugins.put(configuration.getDisplayName(), provider); + } } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBot.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBot.java similarity index 75% rename from leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBot.java rename to leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBot.java index de52608d..e055265e 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBot.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBot.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.bot; import com.google.common.base.Preconditions; import org.bukkit.Location; @@ -9,9 +9,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.BotList; import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; -import org.leavesmc.leaves.bot.agent.actions.CraftBotAction; -import org.leavesmc.leaves.entity.botaction.LeavesBotAction; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; +import org.leavesmc.leaves.entity.bot.actions.CraftBotAction; import org.leavesmc.leaves.event.bot.BotActionStopEvent; import org.leavesmc.leaves.event.bot.BotRemoveEvent; @@ -39,13 +39,16 @@ public class CraftBot extends CraftPlayer implements Bot { } @Override - public void addAction(@NotNull LeavesBotAction action) { - this.getHandle().addBotAction(CraftBotAction.asInternalCopy(action), null); + public > void addAction(@NotNull T action) { + switch (action) { + case CraftBotAction act -> this.getHandle().addBotAction(act.getHandle(), null); + default -> throw new IllegalArgumentException("Action " + action.getClass().getName() + " is not a valid BotAction type!"); + } } @Override - public LeavesBotAction getAction(int index) { - return CraftBotAction.asAPICopy(this.getHandle().getBotActions().get(index)); + public BotAction getAction(int index) { + return (BotAction) this.getHandle().getBotActions().get(index).asCraft(); } @Override @@ -60,7 +63,7 @@ public class CraftBot extends CraftPlayer implements Bot { @Override public void stopAllActions() { - for (AbstractBotAction action : this.getHandle().getBotActions()) { + for (ServerBotAction action : this.getHandle().getBotActions()) { action.stop(this.getHandle(), BotActionStopEvent.Reason.PLUGIN); } } @@ -72,7 +75,7 @@ public class CraftBot extends CraftPlayer implements Bot { } @Override - public boolean teleport(Location location, PlayerTeleportEvent.@NotNull TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) { + public boolean teleport(Location location, PlayerTeleportEvent.@NotNull TeleportCause cause, io.papermc.paper.entity.TeleportFlag @NotNull ... flags) { Preconditions.checkArgument(location != null, "location cannot be null"); Preconditions.checkState(location.getWorld().equals(this.getWorld()), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!"); return super.teleport(location, cause, flags); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java similarity index 69% rename from leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java rename to leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java index d4e0a28a..f7cd9a18 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftBotManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/CraftBotManager.java @@ -1,6 +1,5 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.bot; -import com.google.common.base.Function; import com.google.common.collect.Lists; import net.minecraft.server.MinecraftServer; import org.bukkit.Location; @@ -9,10 +8,9 @@ import org.jetbrains.annotations.Nullable; import org.leavesmc.leaves.bot.BotCreateState; import org.leavesmc.leaves.bot.BotList; import org.leavesmc.leaves.bot.ServerBot; -import org.leavesmc.leaves.bot.agent.AbstractBotAction; import org.leavesmc.leaves.bot.agent.Actions; -import org.leavesmc.leaves.bot.agent.actions.CraftCustomBotAction; -import org.leavesmc.leaves.entity.botaction.CustomBotAction; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; import org.leavesmc.leaves.event.bot.BotCreateEvent; import java.util.Collection; @@ -26,7 +24,7 @@ public class CraftBotManager implements BotManager { public CraftBotManager() { this.botList = MinecraftServer.getServer().getBotList(); - this.botViews = Collections.unmodifiableList(Lists.transform(botList.bots, bot -> bot.getBukkitEntity())); + this.botViews = Collections.unmodifiableList(Lists.transform(botList.bots, ServerBot::getBukkitEntity)); } @Override @@ -54,18 +52,19 @@ public class CraftBotManager implements BotManager { return botViews; } + @SuppressWarnings("unchecked") @Override - public boolean registerCustomBotAction(String name, CustomBotAction action) { - return Actions.register(new CraftCustomBotAction(name, action)); - } - - @Override - public boolean unregisterCustomBotAction(String name) { - AbstractBotAction action = Actions.getForName(name); - if (action instanceof CraftCustomBotAction) { - return Actions.unregister(name); + public > T newAction(@NotNull Class type) { + ServerBotAction action = Actions.getForClass(type); + if (action == null) { + throw new IllegalArgumentException("No action registered for type: " + type.getName()); + } else { + try { + return (T) action.create().asCraft(); + } catch (Exception e) { + throw new RuntimeException("Failed to create action of type: " + type.getName(), e); + } } - return false; } @Override diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftAttackAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftAttackAction.java new file mode 100644 index 00000000..31215043 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftAttackAction.java @@ -0,0 +1,122 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftAttackAction extends CraftBotAction implements AttackAction { + private final ServerAttackAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftAttackAction(ServerAttackAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftAttackAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftAttackAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftAttackAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftBotAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftBotAction.java new file mode 100644 index 00000000..57da8852 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftBotAction.java @@ -0,0 +1,7 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.leavesmc.leaves.bot.agent.actions.*; + +public abstract class CraftBotAction { + public abstract ServerBotAction getHandle(); +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftBreakBlockAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftBreakBlockAction.java new file mode 100644 index 00000000..58c1a14c --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftBreakBlockAction.java @@ -0,0 +1,122 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftBreakBlockAction extends CraftBotAction implements BreakBlockAction { + private final ServerBreakBlockAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftBreakBlockAction(ServerBreakBlockAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftBreakBlockAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftBreakBlockAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftBreakBlockAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftDropAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftDropAction.java new file mode 100644 index 00000000..4336f6d0 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftDropAction.java @@ -0,0 +1,122 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftDropAction extends CraftBotAction implements DropAction { + private final ServerDropAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftDropAction(ServerDropAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftDropAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftDropAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftDropAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftFishAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftFishAction.java new file mode 100644 index 00000000..2c931331 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftFishAction.java @@ -0,0 +1,122 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftFishAction extends CraftBotAction implements FishAction { + private final ServerFishAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftFishAction(ServerFishAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftFishAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftFishAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftFishAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftJumpAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftJumpAction.java new file mode 100644 index 00000000..f6f3ea73 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftJumpAction.java @@ -0,0 +1,122 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftJumpAction extends CraftBotAction implements JumpAction { + private final ServerJumpAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftJumpAction(ServerJumpAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftJumpAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftJumpAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftJumpAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftLookAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftLookAction.java new file mode 100644 index 00000000..83eb913f --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftLookAction.java @@ -0,0 +1,107 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftLookAction extends CraftBotAction implements LookAction { + private final ServerLookAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftLookAction(ServerLookAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftLookAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftLookAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftLookAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public LookAction setPos(Vector pos) { + serverAction.setPos(pos); + return this; + } + + @Override + public Vector getPos() { + return serverAction.getPos(); + } + + @Override + public LookAction setTarget(Player player) { + serverAction.setTarget(((CraftPlayer) player).getHandle()); + return this; + } + + @Override + public Player getTarget() { + return serverAction.getTarget().getBukkitEntity(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftMoveAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftMoveAction.java new file mode 100644 index 00000000..dfdd1bb1 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftMoveAction.java @@ -0,0 +1,93 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftMoveAction extends CraftBotAction implements MoveAction { + private final ServerMoveAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftMoveAction(ServerMoveAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftMoveAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftMoveAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftMoveAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public MoveDirection getDirection() { + return serverAction.getDirection(); + } + + @Override + public MoveAction setDirection(MoveDirection direction) { + serverAction.setDirection(direction); + return this; + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftRotationAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftRotationAction.java new file mode 100644 index 00000000..de4676aa --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftRotationAction.java @@ -0,0 +1,104 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftRotationAction extends CraftBotAction implements RotationAction { + private final ServerRotationAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftRotationAction(ServerRotationAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftRotationAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftRotationAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftRotationAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public RotationAction setYaw(float yaw) { + serverAction.setYaw(yaw); + return this; + } + + @Override + public RotationAction setPitch(float pitch) { + serverAction.setPitch(pitch); + return this; + } + + @Override + public float getYaw() { + return serverAction.getYaw(); + } + + @Override + public float getPitch() { + return serverAction.getPitch(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftSneakAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftSneakAction.java new file mode 100644 index 00000000..9d984c95 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftSneakAction.java @@ -0,0 +1,82 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftSneakAction extends CraftBotAction implements SneakAction { + private final ServerSneakAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftSneakAction(ServerSneakAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftSneakAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftSneakAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftSneakAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftSwimAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftSwimAction.java new file mode 100644 index 00000000..d438e773 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftSwimAction.java @@ -0,0 +1,82 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftSwimAction extends CraftBotAction implements SwimAction { + private final ServerSwimAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftSwimAction(ServerSwimAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftSwimAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftSwimAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftSwimAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemAction.java new file mode 100644 index 00000000..17ae335e --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemAction extends CraftBotAction implements UseItemAction { + private final ServerUseItemAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemAction(ServerUseItemAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemAutoAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemAutoAction.java new file mode 100644 index 00000000..d604cbc8 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemAutoAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemAutoAction extends CraftBotAction implements UseItemAutoAction { + private final ServerUseItemAutoAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemAutoAction(ServerUseItemAutoAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemAutoAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemAutoAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemAutoAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemAutoAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOffhandAction.java new file mode 100644 index 00000000..7ea1534c --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOffhandAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemOffhandAction extends CraftBotAction implements UseItemOffhandAction { + private final ServerUseItemOffhandAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemOffhandAction(ServerUseItemOffhandAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemOffhandAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemOffhandAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemOffhandAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemOffhandAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOnAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOnAction.java new file mode 100644 index 00000000..cb5301c9 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOnAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemOnAction extends CraftBotAction implements UseItemOnAction { + private final ServerUseItemOnAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemOnAction(ServerUseItemOnAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemOnAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemOnAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemOnAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemOnAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOnOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOnOffhandAction.java new file mode 100644 index 00000000..30ea83b8 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemOnOffhandAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemOnOffhandAction extends CraftBotAction implements UseItemOnOffhandAction { + private final ServerUseItemOnOffhandAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemOnOffhandAction(ServerUseItemOnOffhandAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemOnOffhandAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemOnOffhandAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemOnOffhandAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemOnOffhandAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemToAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemToAction.java new file mode 100644 index 00000000..dd7cd8b6 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemToAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemToAction extends CraftBotAction implements UseItemToAction { + private final ServerUseItemToAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemToAction(ServerUseItemToAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemToAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemToAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemToAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemToAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemToOffhandAction.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemToOffhandAction.java new file mode 100644 index 00000000..6715f0a5 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/bot/actions/CraftUseItemToOffhandAction.java @@ -0,0 +1,133 @@ +package org.leavesmc.leaves.entity.bot.actions; + +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.bot.ServerBot; +import org.leavesmc.leaves.bot.agent.actions.*; +import org.leavesmc.leaves.entity.bot.action.*; + +import java.util.UUID; +import java.util.function.Consumer; + +public class CraftUseItemToOffhandAction extends CraftBotAction implements UseItemToOffhandAction { + private final ServerUseItemToOffhandAction serverAction; + private Consumer onFail = null; + private Consumer onSuccess = null; + private Consumer onStop = null; + + public CraftUseItemToOffhandAction(ServerUseItemToOffhandAction serverAction) { + this.serverAction = serverAction; + } + + public boolean doTick(@NotNull ServerBot bot) { + return serverAction.doTick(bot); + } + + @Override + public int getUseTick() { + return serverAction.getUseTick(); + } + + @Override + public CraftUseItemToOffhandAction setUseTick(int useTick) { + serverAction.setUseTick(useTick); + return this; + } + + @Override + public ServerBotAction getHandle() { + return serverAction; + } + + @Override + public String getName() { + return serverAction.getName(); + } + + @Override + public UUID getUUID() { + return serverAction.getUUID(); + } + + @Override + public void setCancelled(boolean cancel) { + serverAction.setCancelled(cancel); + } + + @Override + public boolean isCancelled() { + return serverAction.isCancelled(); + } + + @Override + public void setOnFail(Consumer onFail) { + this.onFail = onFail; + serverAction.setOnFail(it -> onFail.accept(new CraftUseItemToOffhandAction(it))); + } + + @Override + public Consumer getOnFail() { + return onFail; + } + + @Override + public void setOnSuccess(Consumer onSuccess) { + this.onSuccess = onSuccess; + serverAction.setOnSuccess(it -> onSuccess.accept(new CraftUseItemToOffhandAction(it))); + } + + @Override + public Consumer getOnSuccess() { + return onSuccess; + } + + @Override + public void setOnStop(Consumer onStop) { + this.onStop = onStop; + serverAction.setOnStop(it -> onStop.accept(new CraftUseItemToOffhandAction(it))); + } + + @Override + public Consumer getOnStop() { + return onStop; + } + + @Override + public void setStartDelayTick(int delayTick) { + serverAction.setStartDelayTick(delayTick); + } + + @Override + public int getStartDelayTick() { + return serverAction.getStartDelayTick(); + } + + @Override + public void setDoIntervalTick(int intervalTick) { + serverAction.setDoIntervalTick(intervalTick); + } + + @Override + public int getDoIntervalTick() { + return serverAction.getDoIntervalTick(); + } + + @Override + public void setDoNumber(int doNumber) { + serverAction.setDoNumber(doNumber); + } + + @Override + public int getDoNumber() { + return serverAction.getDoNumber(); + } + + @Override + public int getTickToNext() { + return serverAction.getTickToNext(); + } + + @Override + public int getDoNumberRemaining() { + return serverAction.getDoNumberRemaining(); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftPhotographer.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/photographer/CraftPhotographer.java similarity index 97% rename from leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftPhotographer.java rename to leaves-server/src/main/java/org/leavesmc/leaves/entity/photographer/CraftPhotographer.java index fed2005c..1b4d7f72 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftPhotographer.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/photographer/CraftPhotographer.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.photographer; import net.minecraft.server.level.ServerPlayer; import org.bukkit.craftbukkit.CraftServer; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftPhotographerManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/entity/photographer/CraftPhotographerManager.java similarity index 98% rename from leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftPhotographerManager.java rename to leaves-server/src/main/java/org/leavesmc/leaves/entity/photographer/CraftPhotographerManager.java index e87d1e72..797d2941 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/entity/CraftPhotographerManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/entity/photographer/CraftPhotographerManager.java @@ -1,4 +1,4 @@ -package org.leavesmc.leaves.entity; +package org.leavesmc.leaves.entity.photographer; import com.google.common.collect.Lists; import org.bukkit.Location; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java b/leaves-server/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java index 549cc9f4..e814196d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java @@ -1,12 +1,16 @@ +// Gale - Lithium - faster chunk serialization + package org.leavesmc.leaves.lithium.common.world.chunk; -import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.HashCommon; -import it.unimi.dsi.fastutil.objects.Reference2IntMap; import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.ReportedException; import net.minecraft.core.IdMap; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.VarInt; +import net.minecraft.world.level.chunk.MissingPaletteEntryException; import net.minecraft.world.level.chunk.Palette; import net.minecraft.world.level.chunk.PaletteResize; import org.jetbrains.annotations.NotNull; @@ -17,8 +21,6 @@ import java.util.function.Predicate; import static it.unimi.dsi.fastutil.Hash.FAST_LOAD_FACTOR; -// Powered by Gale(https://github.com/GaleMC/Gale) - /** * Generally provides better performance over the vanilla {@link net.minecraft.world.level.chunk.HashMapPalette} when calling * {@link LithiumHashPalette#idFor(Object)} through using a faster backing map and reducing pointer chasing. @@ -30,11 +32,11 @@ public class LithiumHashPalette implements Palette { private final PaletteResize resizeHandler; private final int indexBits; - private final Reference2IntMap table; + private final Reference2IntOpenHashMap table; private T[] entries; private int size = 0; - public LithiumHashPalette(IdMap idList, PaletteResize resizeHandler, int indexBits, T[] entries, Reference2IntMap table, int size) { + private LithiumHashPalette(IdMap idList, PaletteResize resizeHandler, int indexBits, T[] entries, Reference2IntOpenHashMap table, int size) { this.idList = idList; this.resizeHandler = resizeHandler; this.indexBits = indexBits; @@ -43,7 +45,7 @@ public class LithiumHashPalette implements Palette { this.size = size; } - public LithiumHashPalette(IdMap idList, int bits, PaletteResize resizeHandler, @NotNull List list) { + public LithiumHashPalette(IdMap idList, int bits, PaletteResize resizeHandler, List list) { this(idList, bits, resizeHandler); for (T t : list) { @@ -120,14 +122,32 @@ public class LithiumHashPalette implements Palette { } @Override - public T valueFor(int id) { + public @NotNull T valueFor(int id) { T[] entries = this.entries; + T entry = null; if (id >= 0 && id < entries.length) { - return entries[id]; + entry = entries[id]; } - return null; + if (entry != null) { + return entry; + } else { + throw this.missingPaletteEntryCrash(id); + } + } + + private ReportedException missingPaletteEntryCrash(int id) { + try { + throw new MissingPaletteEntryException(id); + } catch (MissingPaletteEntryException e) { + CrashReport crashReport = CrashReport.forThrowable(e, "[Lithium] Getting Palette Entry"); + CrashReportCategory crashReportCategory = crashReport.addCategory("Chunk section"); + crashReportCategory.setDetail("IndexBits", this.indexBits); + crashReportCategory.setDetail("Entries", this.entries.length + " Elements: " + Arrays.toString(this.entries)); + crashReportCategory.setDetail("Table", this.table.size() + " Elements: " + this.table); + return new ReportedException(crashReport); + } } @Override @@ -137,7 +157,7 @@ public class LithiumHashPalette implements Palette { int entryCount = buf.readVarInt(); for (int i = 0; i < entryCount; ++i) { - this.addEntry(this.idList.byId(buf.readVarInt())); + this.addEntry(this.idList.byIdOrThrow(buf.readVarInt())); } } @@ -167,10 +187,9 @@ public class LithiumHashPalette implements Palette { return this.size; } - @NotNull @Override - public Palette copy(@NotNull PaletteResize resizeListener) { - return new LithiumHashPalette<>(this.idList, resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size); + public @NotNull Palette copy(@NotNull PaletteResize resizeHandler) { + return new LithiumHashPalette<>(this.idList, resizeHandler, this.indexBits, this.entries.clone(), this.table.clone(), this.size); } private void clear() { @@ -180,17 +199,11 @@ public class LithiumHashPalette implements Palette { } public List getElements() { - ImmutableList.Builder builder = new ImmutableList.Builder<>(); - for (T entry : this.entries) { - if (entry != null) { - builder.add(entry); - } - } - return builder.build(); + T[] copy = Arrays.copyOf(this.entries, this.size); + return Arrays.asList(copy); } public static Palette create(int bits, IdMap idList, PaletteResize listener, List list) { return new LithiumHashPalette<>(idList, bits, listener, list); } -} - +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/plugin/provider/configuration/MixinConfiguration.java b/leaves-server/src/main/java/org/leavesmc/leaves/plugin/provider/configuration/MixinConfiguration.java index 16462465..77abb231 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/plugin/provider/configuration/MixinConfiguration.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/plugin/provider/configuration/MixinConfiguration.java @@ -15,7 +15,9 @@ public class MixinConfiguration { @PostProcess public void postProcess() { - if (mixins.isEmpty()) return; + if (mixins.isEmpty()) { + return; + } if (packageName == null) { throw new IllegalStateException("Already define mixins: " + mixins + ", but no mixin package-name provided"); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java index c5691277..a6407b37 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java @@ -8,6 +8,7 @@ import net.minecraft.world.level.GameRules; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.protocol.core.Context; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; import org.leavesmc.leaves.protocol.core.ProtocolUtils; @@ -16,6 +17,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.UUID; @LeavesProtocol.Register(namespace = "appleskin") public class AppleSkinProtocol implements LeavesProtocol { @@ -32,7 +34,7 @@ public class AppleSkinProtocol implements LeavesProtocol { private static final Map previousExhaustionLevels = new HashMap<>(); private static final Map previousNaturalRegeneration = new HashMap<>(); - private static final Map> subscribedChannels = new HashMap<>(); + private static final Map> subscribedChannels = new HashMap<>(); @Contract("_ -> new") public static ResourceLocation id(String path) { @@ -46,21 +48,24 @@ public class AppleSkinProtocol implements LeavesProtocol { @ProtocolHandler.PlayerLeave public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { - subscribedChannels.remove(player); + subscribedChannels.remove(player.getUUID()); resetPlayerData(player); } @ProtocolHandler.MinecraftRegister(onlyNamespace = true) - public static void onPlayerSubscribed(@NotNull ServerPlayer player, ResourceLocation id) { - subscribedChannels.computeIfAbsent(player, k -> new HashSet<>()).add(id.getPath()); + public static void onPlayerSubscribed(@NotNull Context context, ResourceLocation id) { + subscribedChannels.computeIfAbsent(context.profile().getId(), k -> new HashSet<>()).add(id.getPath()); } @ProtocolHandler.Ticker public static void tick() { - for (Map.Entry> entry : subscribedChannels.entrySet()) { - ServerPlayer player = entry.getKey(); - FoodData data = player.getFoodData(); + for (Map.Entry> entry : subscribedChannels.entrySet()) { + ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(entry.getKey()); + if (player == null) { + continue; + } + FoodData data = player.getFoodData(); for (String channel : entry.getValue()) { switch (channel) { case "saturation" -> { @@ -82,7 +87,7 @@ public class AppleSkinProtocol implements LeavesProtocol { } case "natural_regeneration" -> { - boolean regeneration = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION); + boolean regeneration = player.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION); Boolean previousRegeneration = previousNaturalRegeneration.get(player); if (previousRegeneration == null || regeneration != previousRegeneration) { ProtocolUtils.sendBytebufPacket(player, NATURAL_REGENERATION_KEY, buf -> buf.writeBoolean(regeneration)); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java index 6dccdb29..6698d367 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java @@ -134,7 +134,7 @@ public class BBORProtocol implements LeavesProtocol { } private static void sendStructureList(@NotNull ServerPlayer player) { - final Registry structureRegistry = player.server.registryAccess().lookupOrThrow(Registries.STRUCTURE); + final Registry structureRegistry = MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.STRUCTURE); final Set structureIds = structureRegistry.entrySet().stream() .map(e -> e.getKey().location().toString()).collect(Collectors.toSet()); ProtocolUtils.sendBytebufPacket(player, STRUCTURE_LIST_SYNC, buf -> { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java index b5dd7f71..fa004637 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java @@ -43,7 +43,7 @@ public class CarpetServerProtocol implements LeavesProtocol { @ProtocolHandler.PayloadReceiver(payload = CarpetPayload.class) private static void handleHello(@NotNull ServerPlayer player, @NotNull CarpetServerProtocol.CarpetPayload payload) { if (payload.nbt.contains(HELLO)) { - LeavesLogger.LOGGER.info("Player " + player.getScoreboardName() + " joined with carpet " + payload.nbt.getString(HELLO)); + LeavesLogger.LOGGER.info("Player " + player.getScoreboardName() + " joined with carpet " + payload.nbt.getString(HELLO).orElse("Unknown")); CompoundTag data = new CompoundTag(); CarpetRules.write(data); ProtocolUtils.sendPayloadPacket(player, new CarpetPayload(data)); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java index ce7ef9ad..16da03c9 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java @@ -1,6 +1,5 @@ package org.leavesmc.leaves.protocol; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -10,6 +9,7 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BedBlock; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.EnumProperty; @@ -23,7 +23,7 @@ import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Map; +import java.util.function.BiFunction; public class LitematicaEasyPlaceProtocol { @@ -51,9 +51,8 @@ public class LitematicaEasyPlaceProtocol { BlockStateProperties.ROTATION_16 ); - public static final ImmutableMap, ?> BLACKLISTED_PROPERTIES = ImmutableMap.of( - BlockStateProperties.WATERLOGGED, false, - BlockStateProperties.POWERED, false + public static final ImmutableSet> DYNAMIC_PROPERTIES = ImmutableSet.of( + (state, original) -> state.setValue(BlockStateProperties.WATERLOGGED, original.is(Blocks.WATER)) ); public static BlockState applyPlacementProtocol(BlockState state, BlockPlaceContext context) { @@ -70,6 +69,14 @@ public class LitematicaEasyPlaceProtocol { } EnumProperty property = CarpetAlternativeBlockPlacement.getFirstDirectionProperty(state); + BlockState original = context.getWorld().getBlockStateIfLoaded(context.pos); + if (original == null) { + return oldState; + } + + for (var func : DYNAMIC_PROPERTIES) { + state = func.apply(state, original); + } if (property != null && property != BlockStateProperties.VERTICAL_DIRECTION) { state = applyDirectionProperty(state, context, property, protocolValue); @@ -97,7 +104,7 @@ public class LitematicaEasyPlaceProtocol { if (property != null && property.equals(p)) { continue; } - if (!WHITELISTED_PROPERTIES.contains(p) || BLACKLISTED_PROPERTIES.containsKey(p)) { + if (!WHITELISTED_PROPERTIES.contains(p)) { continue; } @@ -129,12 +136,6 @@ public class LitematicaEasyPlaceProtocol { LeavesLogger.LOGGER.warning("Exception trying to apply placement protocol value", e); } - for (Map.Entry, ?> p : BLACKLISTED_PROPERTIES.entrySet()) { - if (state.hasProperty(p.getKey())) { - state = state.setValue((Property) p.getKey(), (T) p.getValue()); - } - } - if (state.canSurvive(context.getWorld(), context.getPos())) { return state; } else { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java index fea8d8aa..5a8483f1 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java @@ -31,6 +31,7 @@ import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; import org.leavesmc.leaves.protocol.core.ProtocolUtils; +import org.leavesmc.leaves.util.TagUtil; import java.util.HashMap; import java.util.HashSet; @@ -82,7 +83,7 @@ public class PcaSyncProtocol implements LeavesProtocol { @ProtocolHandler.PayloadReceiver(payload = SyncBlockEntityPayload.class) private static void syncBlockEntityHandler(ServerPlayer player, SyncBlockEntityPayload payload) { BlockPos pos = payload.pos; - ServerLevel world = player.serverLevel(); + ServerLevel world = player.level(); Bukkit.getGlobalRegionScheduler().run(MinecraftInternalPlugin.INSTANCE, (task) -> { BlockState blockState = world.getBlockState(pos); @@ -122,7 +123,7 @@ public class PcaSyncProtocol implements LeavesProtocol { private static void syncEntityHandler(ServerPlayer player, SyncEntityPayload payload) { MinecraftServer server = MinecraftServer.getServer(); int entityId = payload.entityId; - ServerLevel world = player.serverLevel(); + ServerLevel world = player.level(); Bukkit.getGlobalRegionScheduler().run(MinecraftInternalPlugin.INSTANCE, (task) -> { Entity entity = world.getEntity(entityId); @@ -188,7 +189,7 @@ public class PcaSyncProtocol implements LeavesProtocol { } public static void updateEntity(@NotNull ServerPlayer player, @NotNull Entity entity) { - CompoundTag nbt = entity.saveWithoutId(new CompoundTag()); + CompoundTag nbt = TagUtil.saveEntity(entity); ProtocolUtils.sendPayloadPacket(player, new UpdateEntityPayload(entity.level().dimension().location(), entity.getId(), nbt)); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/Context.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/Context.java new file mode 100644 index 00000000..ca17fdb0 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/Context.java @@ -0,0 +1,9 @@ +package org.leavesmc.leaves.protocol.core; + +import com.mojang.authlib.GameProfile; +import net.minecraft.network.Connection; +import org.jetbrains.annotations.NotNull; + +public record Context(@NotNull GameProfile profile, Connection connection) { + +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/IdentifierSelector.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/IdentifierSelector.java new file mode 100644 index 00000000..3fe9d894 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/IdentifierSelector.java @@ -0,0 +1,11 @@ +package org.leavesmc.leaves.protocol.core; + +import net.minecraft.server.level.ServerPlayer; +import org.jetbrains.annotations.Nullable; + +public record IdentifierSelector(@Nullable Context context, @Nullable ServerPlayer player) { + + public Object select(ProtocolHandler.Stage stage) { + return stage == ProtocolHandler.Stage.CONFIGURATION ? context : player; + } +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java index 4c7bf96c..f6300c8e 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/LeavesProtocolManager.java @@ -218,27 +218,27 @@ public class LeavesProtocolManager { codec.encode(ProtocolUtils.decorate(buf), payload); } - public static void handlePayload(ServerPlayer player, LeavesCustomPayload payload) { + public static void handlePayload(IdentifierSelector selector, LeavesCustomPayload payload) { PayloadReceiverInvokerHolder holder; if ((holder = PAYLOAD_RECEIVERS.get(payload.getClass())) != null) { - holder.invoke(player, payload); + holder.invoke(selector, payload); } } - public static boolean handleBytebuf(ServerPlayer player, ResourceLocation location, ByteBuf buf) { + public static boolean handleBytebuf(IdentifierSelector selector, ResourceLocation location, ByteBuf buf) { RegistryFriendlyByteBuf buf1 = ProtocolUtils.decorate(buf); BytebufReceiverInvokerHolder holder; if ((holder = STRICT_BYTEBUF_RECEIVERS.get(location.toString())) != null) { - holder.invoke(player, buf1); + holder.invoke(selector, buf1); return true; } if ((holder = NAMESPACED_BYTEBUF_RECEIVERS.get(location.getNamespace())) != null) { - if (holder.invoke(player, buf1)) { + if (holder.invoke(selector, buf1)) { return true; } } for (var holder1 : GENERIC_BYTEBUF_RECEIVERS) { - if (holder1.invoke(player, buf1)) { + if (holder1.invoke(selector, buf1)) { return true; } } @@ -278,22 +278,22 @@ public class LeavesProtocolManager { } } - public static void handleMinecraftRegister(String channelId, ServerPlayer player) { + public static void handleMinecraftRegister(String channelId, IdentifierSelector selector) { ResourceLocation location = ResourceLocation.tryParse(channelId); if (location == null) { return; } for (var wildHolder : WILD_MINECRAFT_REGISTER) { - wildHolder.invoke(player, location); + wildHolder.invoke(selector, location); } MinecraftRegisterInvokerHolder holder; if ((holder = STRICT_MINECRAFT_REGISTER.get(location.toString())) != null) { - holder.invoke(player, location); + holder.invoke(selector, location); } if ((holder = NAMESPACED_MINECRAFT_REGISTER.get(location.getNamespace())) != null) { - holder.invoke(player, location); + holder.invoke(selector, location); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java index 0a36db38..5aefe65d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java @@ -1,5 +1,7 @@ package org.leavesmc.leaves.protocol.core; +import net.minecraft.server.level.ServerPlayer; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -16,6 +18,8 @@ public class ProtocolHandler { @Retention(RetentionPolicy.RUNTIME) public @interface PayloadReceiver { Class payload(); + + Stage stage() default Stage.GAME; } @Target(ElementType.METHOD) @@ -24,6 +28,8 @@ public class ProtocolHandler { String key() default ""; boolean onlyNamespace() default false; + + Stage stage() default Stage.GAME; } @Target(ElementType.METHOD) @@ -53,10 +59,27 @@ public class ProtocolHandler { String key() default ""; boolean onlyNamespace() default false; + + Stage stage() default Stage.CONFIGURATION; } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface ReloadDataPack { } + + public enum Stage { + CONFIGURATION(Context.class), + GAME(ServerPlayer.class); + + private final Class identifier; + + Stage(Class identifier) { + this.identifier = identifier; + } + + public Class identifier() { + return identifier; + } + } } \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolUtils.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolUtils.java index 361660c6..ec6771d7 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolUtils.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolUtils.java @@ -11,7 +11,10 @@ import net.minecraft.network.protocol.common.custom.DiscardedPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerCommonPacketListenerImpl; +import net.minecraft.server.network.ServerGamePacketListenerImpl; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; import java.util.function.Function; @@ -19,26 +22,50 @@ import java.util.function.Function; public class ProtocolUtils { private static final Function bufDecorator = buf -> buf instanceof RegistryFriendlyByteBuf registry ? registry : new RegistryFriendlyByteBuf(buf, MinecraftServer.getServer().registryAccess()); + private static final byte[] EMPTY = new byte[0]; public static String buildProtocolVersion(String protocol) { return protocol + "-leaves-" + ServerBuildInfo.buildInfo().asString(ServerBuildInfo.StringRepresentation.VERSION_SIMPLE); } public static void sendEmptyPacket(ServerPlayer player, ResourceLocation id) { - player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, null))); + player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY))); } public static void sendBytebufPacket(@NotNull ServerPlayer player, ResourceLocation id, Consumer consumer) { RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer()); consumer.accept(buf); - player.internalConnection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf)))); + player.connection.send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf)))); } public static void sendPayloadPacket(ServerPlayer player, CustomPacketPayload payload) { - player.internalConnection.send(new ClientboundCustomPayloadPacket(payload)); + player.connection.send(new ClientboundCustomPayloadPacket(payload)); + } + + public static void sendEmptyPacket(Context context, ResourceLocation id) { + context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, EMPTY))); + } + + public static void sendBytebufPacket(@NotNull Context context, ResourceLocation id, Consumer consumer) { + RegistryFriendlyByteBuf buf = decorate(Unpooled.buffer()); + consumer.accept(buf); + context.connection().send(new ClientboundCustomPayloadPacket(new DiscardedPayload(id, ByteBufUtil.getBytes(buf)))); + } + + public static void sendPayloadPacket(Context context, CustomPacketPayload payload) { + context.connection().send(new ClientboundCustomPayloadPacket(payload)); } public static RegistryFriendlyByteBuf decorate(ByteBuf buf) { return bufDecorator.apply(buf); } + + public static IdentifierSelector createSelector(ServerCommonPacketListenerImpl common) { + ServerPlayer player = common instanceof ServerGamePacketListenerImpl game ? game.getPlayer() : null; + return new IdentifierSelector(new Context(common.profile, common.connection), player); + } + + public static ByteBuf wrapNullable(byte @Nullable [] data) { + return data == null ? Unpooled.wrappedBuffer(EMPTY) : Unpooled.wrappedBuffer(data); + } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java index 1cac9120..1e974b1b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/AbstractInvokerHolder.java @@ -14,6 +14,7 @@ public abstract class AbstractInvokerHolder { protected final T handler; protected final Class returnType; protected final Class[] parameterTypes; + protected final boolean isStatic; protected AbstractInvokerHolder(LeavesProtocol owner, Method invoker, T handler, @Nullable Class returnType, @NotNull Class... parameterTypes) { this.owner = owner; @@ -21,6 +22,7 @@ public abstract class AbstractInvokerHolder { this.handler = handler; this.returnType = returnType; this.parameterTypes = parameterTypes; + this.isStatic = Modifier.isStatic(invoker.getModifiers()); validateMethodSignature(); } @@ -58,7 +60,7 @@ public abstract class AbstractInvokerHolder { return null; } try { - if (Modifier.isStatic(invoker.getModifiers())) { + if (isStatic) { return invoker.invoke(null, args); } else { return invoker.invoke(owner, args); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/BytebufReceiverInvokerHolder.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/BytebufReceiverInvokerHolder.java index e2c01b8e..958ba57b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/BytebufReceiverInvokerHolder.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/BytebufReceiverInvokerHolder.java @@ -1,7 +1,7 @@ package org.leavesmc.leaves.protocol.core.invoker; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.server.level.ServerPlayer; +import org.leavesmc.leaves.protocol.core.IdentifierSelector; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; @@ -9,10 +9,10 @@ import java.lang.reflect.Method; public class BytebufReceiverInvokerHolder extends AbstractInvokerHolder { public BytebufReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.BytebufReceiver handler) { - super(owner, invoker, handler, null, ServerPlayer.class, FriendlyByteBuf.class); + super(owner, invoker, handler, null, handler.stage().identifier(), FriendlyByteBuf.class); } - public boolean invoke(ServerPlayer player, FriendlyByteBuf buf) { - return invoke0(false, player, buf) instanceof Boolean b && b; + public boolean invoke(IdentifierSelector selector, FriendlyByteBuf buf) { + return invoke0(false, selector.select(handler.stage()), buf) instanceof Boolean b && b; } -} +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/MinecraftRegisterInvokerHolder.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/MinecraftRegisterInvokerHolder.java index c6766bc7..5960042d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/MinecraftRegisterInvokerHolder.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/MinecraftRegisterInvokerHolder.java @@ -1,7 +1,7 @@ package org.leavesmc.leaves.protocol.core.invoker; import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; +import org.leavesmc.leaves.protocol.core.IdentifierSelector; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; @@ -9,10 +9,10 @@ import java.lang.reflect.Method; public class MinecraftRegisterInvokerHolder extends AbstractInvokerHolder { public MinecraftRegisterInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.MinecraftRegister handler) { - super(owner, invoker, handler, null, ServerPlayer.class, ResourceLocation.class); + super(owner, invoker, handler, null, handler.stage().identifier(), ResourceLocation.class); } - public void invoke(ServerPlayer player, ResourceLocation id) { - invoke0(false, player, id); + public void invoke(IdentifierSelector selector, ResourceLocation id) { + invoke0(false, selector.select(handler.stage()), id); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/PayloadReceiverInvokerHolder.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/PayloadReceiverInvokerHolder.java index bed868b5..2801bff1 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/PayloadReceiverInvokerHolder.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/core/invoker/PayloadReceiverInvokerHolder.java @@ -1,6 +1,6 @@ package org.leavesmc.leaves.protocol.core.invoker; -import net.minecraft.server.level.ServerPlayer; +import org.leavesmc.leaves.protocol.core.IdentifierSelector; import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; @@ -9,10 +9,10 @@ import java.lang.reflect.Method; public class PayloadReceiverInvokerHolder extends AbstractInvokerHolder { public PayloadReceiverInvokerHolder(LeavesProtocol owner, Method invoker, ProtocolHandler.PayloadReceiver handler) { - super(owner, invoker, handler, null, ServerPlayer.class, handler.payload()); + super(owner, invoker, handler, null, handler.stage().identifier(), handler.payload()); } - public void invoke(ServerPlayer player, LeavesCustomPayload payload) { - invoke0(false, player, payload); + public void invoke(IdentifierSelector selector, LeavesCustomPayload payload) { + invoke0(false, selector.select(handler.stage()), payload); } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java index ef9c31d2..eab9764e 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java @@ -92,7 +92,7 @@ import java.util.Set; public class JadeProtocol implements LeavesProtocol { public static final String PROTOCOL_ID = "jade"; - public static final String PROTOCOL_VERSION = "7"; + public static final String PROTOCOL_VERSION = "8"; public static final HierarchyLookup> entityDataProviders = new HierarchyLookup<>(Entity.class); public static final PairHierarchyLookup> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class)); public static final WrappedHierarchyLookup> itemStorageProviders = WrappedHierarchyLookup.forAccessor(); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java index 6bc22532..7ea35779 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/Accessor.java @@ -3,13 +3,13 @@ package org.leavesmc.leaves.protocol.jade.accessor; import net.minecraft.nbt.Tag; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamEncoder; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.HitResult; import org.jetbrains.annotations.Nullable; public interface Accessor { - Level getLevel(); + ServerLevel getLevel(); Player getPlayer(); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java index a6d91d97..c6e7829a 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/AccessorImpl.java @@ -5,8 +5,8 @@ import net.minecraft.nbt.ByteArrayTag; import net.minecraft.nbt.Tag; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamEncoder; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.HitResult; import org.apache.commons.lang3.ArrayUtils; @@ -14,20 +14,20 @@ import java.util.function.Supplier; public abstract class AccessorImpl implements Accessor { - private final Level level; + private final ServerLevel level; private final Player player; private final Supplier hit; protected boolean verify; private RegistryFriendlyByteBuf buffer; - public AccessorImpl(Level level, Player player, Supplier hit) { + public AccessorImpl(ServerLevel level, Player player, Supplier hit) { this.level = level; this.player = player; this.hit = hit; } @Override - public Level getLevel() { + public ServerLevel getLevel() { return level; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessor.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessor.java index 133415a3..b981cdd0 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessor.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessor.java @@ -1,8 +1,8 @@ package org.leavesmc.leaves.protocol.jade.accessor; import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @@ -23,7 +23,7 @@ public interface BlockAccessor extends Accessor { @ApiStatus.NonExtendable interface Builder { - Builder level(Level level); + Builder level(ServerLevel level); Builder player(Player player); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java index a94bb9eb..cfcf71b1 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessorImpl.java @@ -6,10 +6,10 @@ import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; @@ -61,14 +61,14 @@ public class BlockAccessorImpl extends AccessorImpl implements B } public static class Builder implements BlockAccessor.Builder { - private Level level; + private ServerLevel level; private Player player; private BlockHitResult hit; private BlockState blockState = Blocks.AIR.defaultBlockState(); private Supplier blockEntity; @Override - public Builder level(Level level) { + public Builder level(ServerLevel level) { this.level = level; return this; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessor.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessor.java index 00fd87b7..f46108cf 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessor.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessor.java @@ -1,8 +1,8 @@ package org.leavesmc.leaves.protocol.jade.accessor; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.EntityHitResult; import org.jetbrains.annotations.ApiStatus; @@ -19,7 +19,7 @@ public interface EntityAccessor extends Accessor { @ApiStatus.NonExtendable interface Builder { - Builder level(Level level); + Builder level(ServerLevel level); Builder player(Player player); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java index 56166c62..6486f4e9 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/EntityAccessorImpl.java @@ -4,10 +4,10 @@ import com.google.common.base.Suppliers; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; @@ -41,13 +41,13 @@ public class EntityAccessorImpl extends AccessorImpl implements } public static class Builder implements EntityAccessor.Builder { - private Level level; + private ServerLevel level; private Player player; private Supplier hit; private Supplier entity; @Override - public Builder level(Level level) { + public Builder level(ServerLevel level) { this.level = level; return this; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/payload/ServerHandshakePayload.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/payload/ServerHandshakePayload.java index 4955e0e1..3a12a8cc 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/payload/ServerHandshakePayload.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/payload/ServerHandshakePayload.java @@ -17,7 +17,12 @@ import java.util.Map; import static org.leavesmc.leaves.protocol.jade.util.JadeCodec.PRIMITIVE_STREAM_CODEC; -public record ServerHandshakePayload(Map serverConfig, List shearableBlocks, List blockProviderIds, List entityProviderIds) implements LeavesCustomPayload { +public record ServerHandshakePayload( + Map serverConfig, + List shearableBlocks, + List blockProviderIds, + List entityProviderIds +) implements LeavesCustomPayload { @ID private static final ResourceLocation PACKET_SERVER_HANDSHAKE = JadeProtocol.id("server_handshake"); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java index ada7b4d5..24f88873 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java @@ -57,7 +57,11 @@ public enum ItemStorageExtensionProvider implements IServerExtensionProvider { return null; } long currentVersion = iterator.getVersion(container); - long gameTime = request.getLevel().getGameTime(); + long gameTime = request.getLevel().getServer().getTickCount(); if (mergedResult != null && iterator.isFinished()) { if (version == currentVersion) { return mergedResult; // content not changed @@ -73,7 +73,7 @@ public class ItemCollector { items.addTo(def, stack.getCount()); } }); - iterator.afterPopulate(count.get()); + iterator.afterPopulate(container, count.get()); if (mergedResult != null && !iterator.isFinished()) { updateCollectingProgress(mergedResult.getFirst()); return mergedResult; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemIterator.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemIterator.java index 4d65e9a8..08ebca52 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemIterator.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/jade/util/ItemIterator.java @@ -15,6 +15,7 @@ public abstract class ItemIterator { protected final int fromIndex; protected boolean finished; protected int currentIndex; + protected float progress; protected ItemIterator(Function containerFinder, int fromIndex) { this.containerFinder = containerFinder; @@ -35,16 +36,19 @@ public abstract class ItemIterator { public abstract Stream populate(T container); + protected abstract int getSlotCount(T container); + public void reset() { currentIndex = fromIndex; finished = false; } - public void afterPopulate(int count) { + public void afterPopulate(T container, int count) { currentIndex += count; if (count == 0 || currentIndex >= 10000) { finished = true; } + progress = (float) (currentIndex - fromIndex) / (getSlotCount(container) - fromIndex); } public float getCollectingProgress() { @@ -52,14 +56,11 @@ public abstract class ItemIterator { } public static abstract class SlottedItemIterator extends ItemIterator { - protected float progress; public SlottedItemIterator(Function containerFinder, int fromIndex) { super(containerFinder, fromIndex); } - protected abstract int getSlotCount(T container); - protected abstract ItemStack getItemInSlot(T container, int slot); @Override @@ -70,7 +71,6 @@ public abstract class ItemIterator { toIndex = slotCount; finished = true; } - progress = (float) (currentIndex - fromIndex) / (slotCount - fromIndex); return IntStream.range(currentIndex, toIndex).mapToObj(slot -> getItemInSlot(container, slot)); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/REIServerProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/REIServerProtocol.java index d708eeb8..8c32ecf3 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/REIServerProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/REIServerProtocol.java @@ -177,7 +177,7 @@ public class REIServerProtocol implements LeavesProtocol { }); } - @ProtocolHandler.MinecraftRegister(onlyNamespace = true) + @ProtocolHandler.MinecraftRegister(onlyNamespace = true, stage = ProtocolHandler.Stage.GAME) public static void onPlayerSubscribed(@NotNull ServerPlayer player, ResourceLocation location) { enabledPlayers.add(player); String channel = location.getPath(); @@ -215,7 +215,7 @@ public class REIServerProtocol implements LeavesProtocol { } BiConsumer consumer = (ignored, c2sWholeBuf) -> { FriendlyByteBuf tmpBuf = new FriendlyByteBuf(Unpooled.buffer()).writeBytes(c2sWholeBuf.readByteArray()); - ItemStack itemStack = tmpBuf.readJsonWithCodec(ItemStack.OPTIONAL_CODEC); + ItemStack itemStack = tmpBuf.readLenientJsonWithCodec(ItemStack.OPTIONAL_CODEC); if (player.getInventory().add(itemStack.copy())) { RegistryFriendlyByteBuf s2cWholeBuf = ProtocolUtils.decorate(Unpooled.buffer()); s2cWholeBuf.writeJsonWithCodec(ItemStack.OPTIONAL_CODEC, itemStack.copy()); @@ -240,7 +240,7 @@ public class REIServerProtocol implements LeavesProtocol { } BiConsumer consumer = (ignored, c2sWholeBuf) -> { FriendlyByteBuf tmpBuf = new FriendlyByteBuf(Unpooled.buffer()).writeBytes(c2sWholeBuf.readByteArray()); - ItemStack itemStack = tmpBuf.readJsonWithCodec(ItemStack.OPTIONAL_CODEC); + ItemStack itemStack = tmpBuf.readLenientJsonWithCodec(ItemStack.OPTIONAL_CODEC); ItemStack stack = itemStack.copy(); AbstractContainerMenu menu = player.containerMenu; if (!menu.getCarried().isEmpty() && ItemStack.isSameItemSameComponents(menu.getCarried(), stack)) { @@ -270,7 +270,7 @@ public class REIServerProtocol implements LeavesProtocol { } BiConsumer consumer = (ignored, c2sWholeBuf) -> { FriendlyByteBuf tmpBuf = new FriendlyByteBuf(Unpooled.buffer()).writeBytes(c2sWholeBuf.readByteArray()); - ItemStack stack = tmpBuf.readJsonWithCodec(ItemStack.OPTIONAL_CODEC); + ItemStack stack = tmpBuf.readLenientJsonWithCodec(ItemStack.OPTIONAL_CODEC); int hotbarSlotId = tmpBuf.readVarInt(); if (hotbarSlotId >= 0 && hotbarSlotId < 9) { AbstractContainerMenu menu = player.containerMenu; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/CustomDisplay.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/CustomDisplay.java index c98be664..7c24bb0e 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/CustomDisplay.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/CustomDisplay.java @@ -32,7 +32,7 @@ public class CustomDisplay extends CraftingDisplay { super(inputs, outputs, location); BitSet row = new BitSet(3); BitSet column = new BitSet(3); - for (int i = 0; i < 9; i++) + for (int i = 0; i < 9; i++) { if (i < inputs.size()) { EntryIngredient stacks = inputs.get(i); if (stacks.stream().anyMatch(stack -> !stack.isEmpty())) { @@ -40,6 +40,7 @@ public class CustomDisplay extends CraftingDisplay { column.set(i % 3); } } + } this.width = column.cardinality(); this.height = row.cardinality(); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/Display.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/Display.java index 3e7b9197..10e31d3b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/Display.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/rei/display/Display.java @@ -120,11 +120,13 @@ public abstract class Display { } if (potion.potion().get().unwrapKey().isPresent() && registeredPotions.add(potion.potion().get().unwrapKey().get().location())) { List input = new ArrayList<>(); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { input.add(arrowIngredient); + } input.add(EntryIngredient.of(itemStack)); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 4; i++) { input.add(arrowIngredient); + } ItemStack outputStack = new ItemStack(Items.TIPPED_ARROW, 8); outputStack.set(DataComponents.POTION_CONTENTS, potion); displays.add(new CustomDisplay(input, List.of(EntryIngredient.of(outputStack)), recipeHolder.id().location())); @@ -192,7 +194,9 @@ public abstract class Display { List displays = new ArrayList<>(); for (Holder additionStack : (Iterable>) recipe.additionIngredient().map(Ingredient::items).orElse(Stream.of())::iterator) { Holder trimMaterial = getMaterialFromIngredient(registryAccess, additionStack).orElse(null); - if (trimMaterial == null) continue; + if (trimMaterial == null) { + continue; + } EntryIngredient baseIngredient = EntryIngredient.ofIngredient(recipe.baseIngredient()); displays.add(new SmithingDisplay.Trimming(List.of( @@ -241,7 +245,9 @@ public abstract class Display { } public static List ofSlotDisplays(Collection slots) { - if (slots instanceof Collection collection && collection.isEmpty()) return Collections.emptyList(); + if (slots instanceof Collection collection && collection.isEmpty()) { + return Collections.emptyList(); + } ImmutableList.Builder ingredients = ImmutableList.builder(); for (SlotDisplay slot : slots) { ingredients.add(ofSlotDisplay(slot)); @@ -252,11 +258,17 @@ public abstract class Display { public static EntryIngredient ofItemTag(TagKey tagKey) { HolderGetter getter = MinecraftServer.getServer().registryAccess().lookupOrThrow(tagKey.registry()); HolderSet.Named holders = getter.get(tagKey).orElse(null); - if (holders == null) return EntryIngredient.empty(); + if (holders == null) { + return EntryIngredient.empty(); + } int size = holders.size(); - if (size == 0) return EntryIngredient.empty(); - if (size == 1) return EntryIngredient.of(new ItemStack(holders.get(0).value())); + if (size == 0) { + return EntryIngredient.empty(); + } + if (size == 1) { + return EntryIngredient.of(new ItemStack(holders.get(0).value())); + } List stackList = new ArrayList<>(); for (Holder t : holders) { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java index 8f5a3a4c..79f48001 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java @@ -19,6 +19,7 @@ import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; import org.leavesmc.leaves.protocol.core.ProtocolUtils; +import org.leavesmc.leaves.util.TagUtil; import java.util.HashMap; import java.util.Map; @@ -38,6 +39,11 @@ public class ServuxEntityDataProtocol implements LeavesProtocol { sendMetadata(player); } + @ProtocolHandler.PlayerLeave + public static void onPlayerLeave(ServerPlayer player) { + readingSessionKeys.remove(player.getUUID()); + } + @ProtocolHandler.PayloadReceiver(payload = EntityDataPayload.class) public static void onPacketReceive(ServerPlayer player, EntityDataPayload payload) { switch (payload.packetType) { @@ -79,8 +85,8 @@ public class ServuxEntityDataProtocol implements LeavesProtocol { public static void onBlockEntityRequest(ServerPlayer player, BlockPos pos) { Bukkit.getGlobalRegionScheduler().run(MinecraftInternalPlugin.INSTANCE, (task) -> { - BlockEntity be = player.serverLevel().getBlockEntity(pos); - CompoundTag nbt = be != null ? be.saveWithoutMetadata(player.registryAccess()) : new CompoundTag(); + BlockEntity be = player.level().getBlockEntity(pos); + CompoundTag nbt = be != null ? be.saveWithFullMetadata(player.registryAccess()) : new CompoundTag(); EntityDataPayload payload = new EntityDataPayload(EntityDataPayloadType.PACKET_S2C_BLOCK_NBT_RESPONSE_SIMPLE); payload.pos = pos.immutable(); @@ -91,8 +97,8 @@ public class ServuxEntityDataProtocol implements LeavesProtocol { public static void onEntityRequest(ServerPlayer player, int entityId) { Bukkit.getGlobalRegionScheduler().run(MinecraftInternalPlugin.INSTANCE, (task) -> { - Entity entity = player.serverLevel().getEntity(entityId); - CompoundTag nbt = entity != null ? entity.saveWithoutId(new CompoundTag()) : new CompoundTag(); + Entity entity = player.level().getEntity(entityId); + CompoundTag nbt = TagUtil.saveEntityWithoutId(entity); EntityDataPayload payload = new EntityDataPayload(EntityDataPayloadType.PACKET_S2C_ENTITY_NBT_RESPONSE_SIMPLE); payload.entityId = entityId; @@ -179,7 +185,7 @@ public class ServuxEntityDataProtocol implements LeavesProtocol { buf.writeVarInt(payload.entityId); buf.writeNbt(payload.nbt); } - case PACKET_S2C_NBT_RESPONSE_DATA, PACKET_C2S_NBT_RESPONSE_DATA -> buf.writeBytes(payload.buffer.readBytes(payload.buffer.readableBytes())); + case PACKET_S2C_NBT_RESPONSE_DATA, PACKET_C2S_NBT_RESPONSE_DATA -> buf.writeBytes(payload.buffer.copy()); case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA -> buf.writeNbt(payload.nbt); } }, diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxHudDataProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxHudDataProtocol.java index f0091b49..70325ded 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxHudDataProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxHudDataProtocol.java @@ -8,6 +8,7 @@ import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.Component; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -22,7 +23,9 @@ import org.leavesmc.leaves.protocol.core.LeavesCustomPayload; import org.leavesmc.leaves.protocol.core.LeavesProtocol; import org.leavesmc.leaves.protocol.core.ProtocolHandler; import org.leavesmc.leaves.protocol.core.ProtocolUtils; +import org.leavesmc.leaves.protocol.servux.logger.DataLogger; +import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -32,34 +35,72 @@ import java.util.Map; @LeavesProtocol.Register(namespace = "servux") public class ServuxHudDataProtocol implements LeavesProtocol { - public static final int PROTOCOL_VERSION = 1; + public static final int PROTOCOL_VERSION = 2; private static final List players = new ArrayList<>(); private static final int updateInterval = 80; + private static final HashMap> loggerPlayers = new HashMap<>(); + private static final HashMap> LOGGERS = new HashMap<>(); + private static final HashMap DATA = new HashMap<>(); + public static boolean refreshSpawnMetadata = false; + @ProtocolHandler.Init + private static void initializeLoggers() { + if (!LOGGERS.isEmpty()) { + return; + } + for (DataLogger.Type type : DataLogger.Type.VALUES) { + DataLogger entry = type.init(); + if (entry != null) { + LOGGERS.put(type, entry); + } + } + } + + @ProtocolHandler.PlayerJoin + private static void onPlayerJoin(ServerPlayer player) { + sendHudMetadata(player); + } + + @ProtocolHandler.PlayerLeave + private static void onPlayerLeave(ServerPlayer player) { + players.remove(player); + loggerPlayers.remove(player); + } + @ProtocolHandler.PayloadReceiver(payload = HudDataPayload.class) public static void onPacketReceive(ServerPlayer player, HudDataPayload payload) { switch (payload.packetType) { case PACKET_C2S_METADATA_REQUEST -> { players.add(player); - - CompoundTag metadata = new CompoundTag(); - metadata.putString("name", "hud_metadata"); - metadata.putString("id", HudDataPayload.CHANNEL.toString()); - metadata.putInt("version", PROTOCOL_VERSION); - metadata.putString("servux", ServuxProtocol.SERVUX_STRING); - putWorldData(metadata); - - sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_METADATA, metadata)); + sendHudMetadata(player); } - case PACKET_C2S_SPAWN_DATA_REQUEST -> refreshSpawnMetadata(player); case PACKET_C2S_RECIPE_MANAGER_REQUEST -> refreshRecipeManager(player); + case PACKET_C2S_DATA_LOGGER_REQUEST -> refreshLoggers(player, payload.nbt); } } + public static void sendHudMetadata(ServerPlayer player) { + CompoundTag metadata = new CompoundTag(); + metadata.putString("name", "hud_metadata"); + metadata.putString("id", HudDataPayload.CHANNEL.toString()); + metadata.putInt("version", PROTOCOL_VERSION); + metadata.putString("servux", ServuxProtocol.SERVUX_STRING); + if (LeavesConfig.protocol.servux.hudLoggerProtocol) { + CompoundTag nbt = new CompoundTag(); + for (DataLogger.Type type : DataLogger.Type.VALUES) { + nbt.putBoolean(type.getSerializedName(), isLoggerTypeEnabled(type)); + } + metadata.put("Loggers", nbt); + } + putWorldData(metadata); + + sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_METADATA, metadata)); + } + public static void refreshSpawnMetadata(ServerPlayer player) { CompoundTag metadata = new CompoundTag(); metadata.putString("id", HudDataPayload.CHANNEL.toString()); @@ -70,7 +111,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol { } public static void refreshRecipeManager(ServerPlayer player) { - Collection> recipes = player.server.getRecipeManager().getRecipes(); + Collection> recipes = MinecraftServer.getServer().getRecipeManager().getRecipes(); CompoundTag nbt = new CompoundTag(); ListTag list = new ListTag(); @@ -92,7 +133,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol { public static void refreshWeatherData(ServerPlayer player) { ServerLevel level = MinecraftServer.getServer().overworld(); - if (level.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE)) { + if (!level.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE)) { return; } @@ -134,6 +175,91 @@ public class ServuxHudDataProtocol implements LeavesProtocol { } } + public static void refreshLoggers(ServerPlayer player, @Nonnull CompoundTag nbt) { + if (!player.getBukkitEntity().hasPermission("servux.provider.hud_data.logger")) { + player.sendSystemMessage(Component.translatable("servux.hud_data.error.insufficient_for_loggers", "any")); + return; + } + + if (nbt.isEmpty()) { + return; + } + + List list = new ArrayList<>(); + + for (String key : nbt.keySet()) { + DataLogger.Type type = DataLogger.Type.fromStringStatic(key); + + if (type != null && nbt.getBooleanOr(key, false)) { + list.add(type); + } + } + if (!list.isEmpty()) { + loggerPlayers.put(player, list); + } else { + loggerPlayers.remove(player); + } + } + + private static boolean isLoggerTypeEnabled(DataLogger.Type type) { + return LeavesConfig.protocol.servux.hudEnabledLoggers.contains(type); + } + + @ProtocolHandler.Ticker + public void protocolTick() { + for (ServerPlayer player : players) { + if (refreshSpawnMetadata) { + refreshSpawnMetadata(player); + } + refreshWeatherData(player); + } + refreshSpawnMetadata = false; + } + + @ProtocolHandler.Ticker(tickerId = "logger") + public void loggerTick() { + if (!LeavesConfig.protocol.servux.hudLoggerProtocol) { + return; + } + + MinecraftServer server = MinecraftServer.getServer(); + + if (server.getTickCount() % LeavesConfig.protocol.servux.hudUpdateInterval == 0) { + DATA.clear(); + LOGGERS.forEach((type, logger) -> { + if (!isLoggerTypeEnabled(type)) { + return; + } + DATA.put(type, logger.getResult(server)); + }); + } + + for (ServerPlayer player : loggerPlayers.keySet()) { + List list = loggerPlayers.get(player); + if (list.isEmpty()) { + return; + } + + CompoundTag nbt = new CompoundTag(); + for (DataLogger.Type type : list) { + if (DATA.containsKey(type)) { + nbt.put(type.getSerializedName(), DATA.get(type)); + } + } + sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_DATA_LOGGER_TICK, nbt)); + } + } + + @Override + public boolean isActive() { + return LeavesConfig.protocol.servux.hudMetadataProtocol; + } + + @Override + public int tickerInterval(String tickerID) { + return tickerID.equals("logger") ? 1 : updateInterval; + } + public static void sendPacket(ServerPlayer player, HudDataPayload payload) { if (payload.packetType == HudDataPayloadType.PACKET_S2C_NBT_RESPONSE_START) { FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer()); @@ -148,27 +274,6 @@ public class ServuxHudDataProtocol implements LeavesProtocol { sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_NBT_RESPONSE_DATA, buf)); } - @ProtocolHandler.Ticker - public void onTick() { - for (ServerPlayer player : players) { - if (refreshSpawnMetadata) { - refreshSpawnMetadata(player); - } - refreshWeatherData(player); - } - refreshSpawnMetadata = false; - } - - @Override - public boolean isActive() { - return LeavesConfig.protocol.servux.hudMetadataProtocol; - } - - @Override - public int tickerInterval(String tickerID) { - return updateInterval; - } - public enum HudDataPayloadType { PACKET_S2C_METADATA(1), PACKET_C2S_METADATA_REQUEST(2), @@ -176,6 +281,8 @@ public class ServuxHudDataProtocol implements LeavesProtocol { PACKET_C2S_SPAWN_DATA_REQUEST(4), PACKET_S2C_WEATHER_TICK(5), PACKET_C2S_RECIPE_MANAGER_REQUEST(6), + PACKET_S2C_DATA_LOGGER_TICK(7), + PACKET_C2S_DATA_LOGGER_REQUEST(8), // For Packet Splitter (Oversize Packets, S2C) PACKET_S2C_NBT_RESPONSE_START(10), PACKET_S2C_NBT_RESPONSE_DATA(11); @@ -208,7 +315,8 @@ public class ServuxHudDataProtocol implements LeavesProtocol { switch (payload.packetType()) { case PACKET_S2C_NBT_RESPONSE_DATA -> buf.writeBytes(payload.buffer().copy()); case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA, PACKET_C2S_SPAWN_DATA_REQUEST, - PACKET_S2C_SPAWN_DATA, PACKET_S2C_WEATHER_TICK, PACKET_C2S_RECIPE_MANAGER_REQUEST -> buf.writeNbt(payload.nbt()); + PACKET_S2C_SPAWN_DATA, PACKET_S2C_WEATHER_TICK, PACKET_C2S_RECIPE_MANAGER_REQUEST, + PACKET_C2S_DATA_LOGGER_REQUEST, PACKET_S2C_DATA_LOGGER_TICK -> buf.writeNbt(payload.nbt()); } }, buf -> { @@ -221,7 +329,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol { return new HudDataPayload(type, new FriendlyByteBuf(buf.readBytes(buf.readableBytes()))); } case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA, PACKET_C2S_SPAWN_DATA_REQUEST, PACKET_S2C_SPAWN_DATA, PACKET_S2C_WEATHER_TICK, - PACKET_C2S_RECIPE_MANAGER_REQUEST -> { + PACKET_C2S_RECIPE_MANAGER_REQUEST, PACKET_C2S_DATA_LOGGER_REQUEST, PACKET_S2C_DATA_LOGGER_TICK -> { return new HudDataPayload(type, buf.readNbt()); } } @@ -236,6 +344,5 @@ public class ServuxHudDataProtocol implements LeavesProtocol { public HudDataPayload(HudDataPayloadType type, FriendlyByteBuf buffer) { this(type, new CompoundTag(), buffer); } - } } \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java index 99b413f1..6b4421f9 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java @@ -64,6 +64,7 @@ public class ServuxStructuresProtocol implements LeavesProtocol { @ProtocolHandler.PlayerLeave public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { players.remove(player.getId()); + timeouts.remove(player.getUUID()); } @ProtocolHandler.Ticker @@ -77,11 +78,6 @@ public class ServuxStructuresProtocol implements LeavesProtocol { } } - @Override - public int tickerInterval(String tickerID) { - return updateInterval; - } - public static void onStartedWatchingChunk(ServerPlayer player, LevelChunk chunk) { MinecraftServer server = player.getServer(); if (players.containsKey(player.getId()) && server != null) { @@ -142,7 +138,7 @@ public class ServuxStructuresProtocol implements LeavesProtocol { public static void initialSyncStructures(ServerPlayer player, int chunkRadius, int tickCounter) { UUID uuid = player.getUUID(); ChunkPos center = player.getLastSectionPos().chunk(); - Map references = getStructureReferences(player.serverLevel(), center, chunkRadius); + Map references = getStructureReferences(player.level(), center, chunkRadius); timeouts.remove(uuid); @@ -186,7 +182,7 @@ public class ServuxStructuresProtocol implements LeavesProtocol { } public static void sendStructures(ServerPlayer player, Map references, int tickCounter) { - ServerLevel world = player.serverLevel(); + ServerLevel world = player.level(); Map starts = getStructureStarts(world, references); if (!starts.isEmpty()) { @@ -265,7 +261,7 @@ public class ServuxStructuresProtocol implements LeavesProtocol { } if (!positionsToUpdate.isEmpty()) { - ServerLevel world = player.serverLevel(); + ServerLevel world = player.level(); ChunkPos center = player.getLastSectionPos().chunk(); Map references = new HashMap<>(); @@ -318,6 +314,11 @@ public class ServuxStructuresProtocol implements LeavesProtocol { sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA, buf)); } + @Override + public int tickerInterval(String tickerID) { + return updateInterval; + } + @Override public boolean isActive() { return LeavesConfig.protocol.servux.structureProtocol; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java index f7f60f48..5e82ea37 100755 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/ServuxLitematicsProtocol.java @@ -32,6 +32,7 @@ import org.leavesmc.leaves.protocol.servux.ServuxProtocol; import org.leavesmc.leaves.protocol.servux.litematics.placement.SchematicPlacement; import org.leavesmc.leaves.protocol.servux.litematics.utils.NbtUtils; import org.leavesmc.leaves.protocol.servux.litematics.utils.ReplaceBehavior; +import org.leavesmc.leaves.util.TagUtil; import java.util.HashMap; import java.util.List; @@ -131,7 +132,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { if (!hasPermission(player)) { return; } - BlockEntity be = player.serverLevel().getBlockEntity(pos); + BlockEntity be = player.level().getBlockEntity(pos); CompoundTag tag = be != null ? be.saveWithFullMetadata(MinecraftServer.getServer().registryAccess()) : new CompoundTag(); ServuxLitematicaPayload payload = new ServuxLitematicaPayload(ServuxLitematicaPayloadType.PACKET_S2C_BLOCK_NBT_RESPONSE_SIMPLE); payload.pos = pos; @@ -143,7 +144,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { if (!hasPermission(player)) { return; } - Entity entity = player.serverLevel().getEntity(entityId); + Entity entity = player.level().getEntity(entityId); if (entity == null) { return; } @@ -152,11 +153,11 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { payload.entityId = entityId; if (entity instanceof net.minecraft.world.entity.player.Player) { ResourceLocation loc = EntityType.getKey(entity.getType()); - tag = entity.saveWithoutId(tag); + tag = TagUtil.saveEntity(entity); tag.putString("id", loc.toString()); payload.nbt = tag; encodeServerData(player, payload); - } else if (entity.saveAsPassenger(tag)) { + } else if (TagUtil.saveEntityAsPassenger(entity, tag)) { payload.nbt = tag; encodeServerData(player, payload); } @@ -167,7 +168,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { return; } - ServerLevel world = player.serverLevel(); + ServerLevel world = player.level(); ChunkAccess chunk = world.getChunk(chunkPos.x, chunkPos.z, ChunkStatus.FULL, false); if (chunk == null) { @@ -194,14 +195,14 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { } BlockEntity be = world.getBlockEntity(tePos); - CompoundTag beTag = be != null ? be.saveWithId(player.registryAccess()) : new CompoundTag(); + CompoundTag beTag = TagUtil.saveTileWithId(be); tileList.add(beTag); } for (Entity entity : entities) { CompoundTag entTag = new CompoundTag(); - if (entity.save(entTag)) { + if (TagUtil.saveEntity(entity, entTag)) { Vec3 posVec = new Vec3(entity.getX() - pos1.getX(), entity.getY() - pos1.getY(), entity.getZ() - pos1.getZ()); NbtUtils.writeEntityPositionToTag(posVec, entTag); entTag.putInt("entityId", entity.getId()); @@ -235,7 +236,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol { if (tags.getStringOr("Task", "").equals("LitematicaPaste")) { ServuxProtocol.LOGGER.debug("litematic_data: Servux Paste request from player {}", player.getName().getString()); - ServerLevel serverLevel = player.serverLevel(); + ServerLevel serverLevel = player.level(); long timeStart = System.currentTimeMillis(); SchematicPlacement placement = SchematicPlacement.createFromNbt(tags); ReplaceBehavior replaceMode = ReplaceBehavior.fromStringStatic(tags.getStringOr("ReplaceMode", ReplaceBehavior.NONE.name())); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java index 31835231..61bf0d14 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/placement/SchematicPlacement.java @@ -169,7 +169,9 @@ public class SchematicPlacement { public ImmutableMap getSubRegionBoxFor(String regionName, SubRegionPlacement.RequiredEnabled required) { SubRegionPlacement placement = this.relativeSubRegionPlacements.get(regionName); - if (placement == null) return ImmutableMap.of(); + if (placement == null) { + return ImmutableMap.of(); + } ImmutableMap.Builder builder = ImmutableMap.builder(); Map areaSizes = this.schematic.getAreaSizes(); @@ -236,7 +238,9 @@ public class SchematicPlacement { BlockPos tmp; BlockPos boxPos1 = box.pos1(); BlockPos boxPos2 = box.pos2(); - if (boxPos1 == null || boxPos2 == null) continue; + if (boxPos1 == null || boxPos2 == null) { + continue; + } tmp = PositionUtils.getMinCorner(boxPos1, boxPos2); if (pos1 == null) { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/EntityUtils.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/EntityUtils.java index 5586a54d..c031382d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/EntityUtils.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/EntityUtils.java @@ -8,6 +8,7 @@ import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.Level; +import org.leavesmc.leaves.util.TagFactory; import javax.annotation.Nullable; import java.util.Optional; @@ -18,7 +19,7 @@ public class EntityUtils { @Nullable private static Entity createEntityFromNBTSingle(CompoundTag nbt, Level world) { try { - Optional optional = EntityType.create(nbt, world, EntitySpawnReason.LOAD); + Optional optional = EntityType.create(TagFactory.input(nbt), world, EntitySpawnReason.LOAD); if (optional.isPresent()) { Entity entity = optional.get(); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/SchematicPlacingUtils.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/SchematicPlacingUtils.java index 161c8751..1ecd8e59 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/SchematicPlacingUtils.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/litematics/utils/SchematicPlacingUtils.java @@ -5,7 +5,6 @@ import net.minecraft.core.Direction; import net.minecraft.core.Vec3i; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.Container; import net.minecraft.world.entity.Display; @@ -30,6 +29,7 @@ import org.leavesmc.leaves.protocol.servux.litematics.LitematicaSchematic; import org.leavesmc.leaves.protocol.servux.litematics.container.LitematicaBlockStateContainer; import org.leavesmc.leaves.protocol.servux.litematics.placement.SchematicPlacement; import org.leavesmc.leaves.protocol.servux.litematics.placement.SubRegionPlacement; +import org.leavesmc.leaves.util.TagUtil; import javax.annotation.Nullable; import java.util.List; @@ -210,7 +210,7 @@ public class SchematicPlacingUtils { NbtUtils.writeBlockPosToTag(pos, teNBT); try { - te.loadWithComponents(teNBT, MinecraftServer.getServer().registryAccess()); + TagUtil.loadTileWithComponents(te, teNBT); } catch (Exception e) { ServuxProtocol.LOGGER.warn("Failed to load BlockEntity data for {} @ {}", state, pos); } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/DataLogger.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/DataLogger.java new file mode 100644 index 00000000..dbff3b0a --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/DataLogger.java @@ -0,0 +1,153 @@ +package org.leavesmc.leaves.protocol.servux.logger; + +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Codec; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.ServerTickRateManager; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.NaturalSpawner; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.protocol.servux.logger.data.MobCapData; +import org.leavesmc.leaves.protocol.servux.logger.data.TickData; + +import java.util.ArrayList; +import java.util.function.Function; + +public abstract class DataLogger { + + private final Type type; + + public DataLogger(Type type) { + this.type = type; + } + + public Type getType() { + return this.type; + } + + public abstract T getResult(MinecraftServer server); + + public enum Type implements StringRepresentable { + TPS("tps", Tps::new, Tps.CODEC), + MOB_CAPS("mob_caps", MobCaps::new, MobCaps.CODEC); + + public static final StringRepresentable.EnumCodec CODEC = StringRepresentable.fromEnum(Type::values); + public static final ImmutableList VALUES = ImmutableList.copyOf(values()); + + private final String name; + private final Function> factory; + private final Codec codec; + + Type(String name, Function> factory, Codec codec) { + this.name = name; + this.factory = factory; + this.codec = codec; + } + + public static @Nullable Type fromStringStatic(String name) { + for (Type type : VALUES) { + if (type.name.equalsIgnoreCase(name)) { + return type; + } + } + + return null; + } + + public Function> getFactory() { + return factory; + } + + public @Nullable DataLogger init() { + return this.factory.apply(this); + } + + public Codec codec() { + return this.codec; + } + + @Override + public @NotNull String getSerializedName() { + return name; + } + } + + public static class Tps extends DataLogger { + + public static final Codec CODEC = CompoundTag.CODEC; + + public Tps(Type type) { + super(type); + } + + @Override + public CompoundTag getResult(MinecraftServer server) { + try { + return (CompoundTag) TickData.CODEC.encodeStart(server.registryAccess().createSerializationContext(NbtOps.INSTANCE), this.build(server)).getOrThrow(); + } catch (Exception e) { + return new CompoundTag(); + } + } + + private TickData build(MinecraftServer server) { + ServerTickRateManager tickManager = server.tickRateManager(); + boolean frozen = tickManager.isFrozen(); + boolean sprinting = tickManager.isSprinting(); + final double mspt = server.tickTimes5s.getAverage(); + double tps = 1000.0D / Math.max(sprinting ? 0.0 : tickManager.millisecondsPerTick(), mspt); + + if (frozen) { + tps = 0.0d; + } + + return new TickData( + mspt, tps, + tickManager.getRemainingSprintTicks(), + frozen, sprinting, + tickManager.isSteppingForward() + ); + } + } + + public static class MobCaps extends DataLogger { + + public static final Codec CODEC = CompoundTag.CODEC; + + public MobCaps(Type type) { + super(type); + } + + @Override + public CompoundTag getResult(MinecraftServer server) { + CompoundTag nbt = new CompoundTag(); + + for (ServerLevel world : server.getAllLevels()) { + NaturalSpawner.SpawnState info = world.getChunkSource().getLastSpawnState(); + if (info == null) { + continue; + } + + int chunks = info.getSpawnableChunkCount(); + Object2IntMap counts = info.getMobCategoryCounts(); + MobCapData mobCapData = new MobCapData(new ArrayList<>(), world.getGameTime()); + for (MobCategory category : MobCategory.values()) { + mobCapData.data().add(new MobCapData.Cap(counts.getOrDefault(category, 0), NaturalSpawner.globalLimitForCategory(world, category, chunks))); + } + + try { + nbt.put(world.dimension().location().toString(), MobCapData.CODEC.encodeStart(world.registryAccess().createSerializationContext(NbtOps.INSTANCE), mobCapData).getPartialOrThrow()); + } catch (Exception ignored) { + } + } + + return nbt; + } + } +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/data/MobCapData.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/data/MobCapData.java new file mode 100644 index 00000000..60921024 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/data/MobCapData.java @@ -0,0 +1,33 @@ +package org.leavesmc.leaves.protocol.servux.logger.data; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.PrimitiveCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.world.entity.MobCategory; + +import java.util.List; + +public record MobCapData(List data, long worldTick) { + public static final int CAP_COUNT = MobCategory.values().length; + + private static MobCapData of(int count, List data, long worldTick) { + return new MobCapData(data, worldTick); + } + + public static final Codec CODEC = RecordCodecBuilder.create( + (inst) -> inst.group( + PrimitiveCodec.INT.fieldOf("cap_count").forGetter($ -> CAP_COUNT), + Codec.list(Cap.CODEC).fieldOf("cap_data").forGetter(MobCapData::data), + PrimitiveCodec.LONG.fieldOf("WorldTick").forGetter(MobCapData::worldTick) + ).apply(inst, MobCapData::of) + ); + + public record Cap(int current, int cap) { + public static Codec CODEC = RecordCodecBuilder.create( + (inst) -> inst.group( + PrimitiveCodec.INT.fieldOf("current").forGetter(Cap::current), + PrimitiveCodec.INT.fieldOf("cap").forGetter(Cap::cap) + ).apply(inst, Cap::new) + ); + } +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/data/TickData.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/data/TickData.java new file mode 100644 index 00000000..d244ae86 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/servux/logger/data/TickData.java @@ -0,0 +1,18 @@ +package org.leavesmc.leaves.protocol.servux.logger.data; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.PrimitiveCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +public record TickData(double mspt, double tps, long sprintTicks, boolean frozen, boolean sprinting, boolean stepping) { + public static Codec CODEC = RecordCodecBuilder.create( + (inst) -> inst.group( + PrimitiveCodec.DOUBLE.fieldOf("mspt").forGetter(TickData::mspt), + PrimitiveCodec.DOUBLE.fieldOf("tps").forGetter(TickData::tps), + PrimitiveCodec.LONG.fieldOf("sprintTicks").forGetter(TickData::sprintTicks), + PrimitiveCodec.BOOL.fieldOf("frozen").forGetter(TickData::frozen), + PrimitiveCodec.BOOL.fieldOf("sprinting").forGetter(TickData::sprinting), + PrimitiveCodec.BOOL.fieldOf("stepping").forGetter(TickData::stepping) + ).apply(inst, TickData::new) + ); +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java index 2c7ca6c1..d75bd86b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/ServerPlacement.java @@ -28,12 +28,20 @@ public class ServerPlacement { public ServerPlacement(final UUID id, final String fileName, final UUID hashValue, final PlayerIdentifier owner) { this.id = id; - this.fileName = fileName; + this.fileName = removeExtension(fileName); this.hashValue = hashValue; this.owner = owner; lastModifiedBy = owner; } + private static String removeExtension(final String fileName) { + final int pos = fileName.lastIndexOf("."); + if (pos < 0) { + return fileName; + } + return fileName.substring(0, pos); + } + @Nullable public static ServerPlacement fromJson(final @NotNull JsonObject obj) { if (obj.has("id") diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java index ed239bda..cee6e2c9 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -81,11 +82,16 @@ public class SyncmaticaProtocol { @NotNull public static String sanitizeFileName(final @NotNull String badFileName) { + String input = badFileName; + try { + input = Paths.get(input).getFileName().toString(); + } catch (Exception ignored) { + } final StringBuilder sanitized = new StringBuilder(); - final int len = badFileName.codePointCount(0, badFileName.length()); + final int len = input.codePointCount(0, input.length()); for (int i = 0; i < len; i++) { - final int c = badFileName.codePointAt(i); + final int c = input.codePointAt(i); if (Arrays.binarySearch(ILLEGAL_CHARS, c) < 0) { sanitized.appendCodePoint(c); if (sanitized.length() == 255) { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/region/linear/LinearRegionFile.java b/leaves-server/src/main/java/org/leavesmc/leaves/region/linear/LinearRegionFile.java index 07982b9c..d7cc1a0b 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/region/linear/LinearRegionFile.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/region/linear/LinearRegionFile.java @@ -205,7 +205,9 @@ public class LinearRegionFile implements IRegionFile { while (true) { byte featureNameLength = buffer.get(); - if (featureNameLength == 0) break; + if (featureNameLength == 0) { + break; + } byte[] featureNameBytes = new byte[featureNameLength]; buffer.get(featureNameBytes); String featureName = new String(featureNameBytes); @@ -227,12 +229,16 @@ public class LinearRegionFile implements IRegionFile { bucketBuffers[i] = new byte[bucketSizes[i]]; buffer.get(bucketBuffers[i]); long rawHash = LongHashFunction.xx().hashBytes(bucketBuffers[i]); - if (rawHash != bucketHashes[i]) throw new IOException("Region file hash incorrect " + this.regionFile); + if (rawHash != bucketHashes[i]) { + throw new IOException("Region file hash incorrect " + this.regionFile); + } } } long footerSuperBlock = buffer.getLong(); - if (footerSuperBlock != SUPERBLOCK) throw new IOException("Footer superblock invalid " + this.regionFile); + if (footerSuperBlock != SUPERBLOCK) { + throw new IOException("Footer superblock invalid " + this.regionFile); + } } private synchronized void markToSave() { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java b/leaves-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java index d1d34793..8ab96394 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/replay/Recorder.java @@ -1,6 +1,7 @@ package org.leavesmc.leaves.replay; import com.mojang.serialization.DynamicOps; +import io.netty.channel.ChannelFutureListener; import io.netty.channel.local.LocalChannel; import net.minecraft.SharedConstants; import net.minecraft.core.LayeredRegistryAccess; @@ -9,7 +10,6 @@ import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.Connection; import net.minecraft.network.ConnectionProtocol; -import net.minecraft.network.PacketSendListener; import net.minecraft.network.protocol.BundlePacket; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; @@ -87,7 +87,7 @@ public class Recorder extends Connection { metaData.singleplayer = false; metaData.serverName = recorderOption.serverName; metaData.date = startTime; - metaData.mcversion = SharedConstants.getCurrentVersion().getName(); + metaData.mcversion = SharedConstants.getCurrentVersion().name(); // TODO start event this.savePacket(new ClientboundLoginFinishedPacket(photographer.getGameProfile()), ConnectionProtocol.LOGIN); @@ -169,7 +169,7 @@ public class Recorder extends Connection { } @Override - public void send(@NotNull Packet packet, @Nullable PacketSendListener callbacks, boolean flush) { + public void send(@NotNull Packet packet, @Nullable ChannelFutureListener callbacks, boolean flush) { if (!stopped) { if (packet instanceof BundlePacket packet1) { packet1.subPackets().forEach(subPacket -> send(subPacket, null)); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java b/leaves-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java index 4b1579b1..4c93b3f5 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/replay/ReplayFile.java @@ -111,7 +111,7 @@ public class ReplayFile { public void saveMetaData(@NotNull RecordMetaData data) throws IOException { data.fileFormat = "MCPR"; data.fileFormatVersion = RecordMetaData.CURRENT_FILE_FORMAT_VERSION; - data.protocol = SharedConstants.getCurrentVersion().getProtocolVersion(); + data.protocol = SharedConstants.getCurrentVersion().protocolVersion(); data.generator = ProtocolUtils.buildProtocolVersion("replay"); try (Writer writer = new OutputStreamWriter(new FileOutputStream(metaFile), StandardCharsets.UTF_8)) { diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java b/leaves-server/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java index d1eb8b9e..bb45d241 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java @@ -14,8 +14,8 @@ import org.bukkit.craftbukkit.CraftWorld; import org.jetbrains.annotations.NotNull; import org.leavesmc.leaves.LeavesLogger; import org.leavesmc.leaves.bot.BotStatsCounter; -import org.leavesmc.leaves.entity.CraftPhotographer; -import org.leavesmc.leaves.entity.Photographer; +import org.leavesmc.leaves.entity.photographer.CraftPhotographer; +import org.leavesmc.leaves.entity.photographer.Photographer; import java.io.File; import java.io.IOException; @@ -61,7 +61,7 @@ public class ServerPhotographer extends ServerPlayer { photographer.recorder.start(); MinecraftServer.getServer().getPlayerList().placeNewPhotographer(photographer.recorder, photographer, world); - photographer.serverLevel().chunkSource.move(photographer); + photographer.level().chunkSource.move(photographer); photographer.setInvisible(true); photographers.add(photographer); @@ -77,9 +77,9 @@ public class ServerPhotographer extends ServerPlayer { super.tick(); super.doTick(); - if (this.server.getTickCount() % 10 == 0) { + if (this.getServer().getTickCount() % 10 == 0) { connection.resetPosition(); - this.serverLevel().chunkSource.move(this); + this.level().chunkSource.move(this); } if (this.followPlayer != null) { @@ -129,7 +129,7 @@ public class ServerPhotographer extends ServerPlayer { super.remove(RemovalReason.KILLED); photographers.remove(this); this.recorder.stop(); - this.server.getPlayerList().removePhotographer(this); + this.getServer().getPlayerList().removePhotographer(this); LeavesLogger.LOGGER.info("Photographer " + createState.id + " removed"); diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/BlockPatternHelper.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/BlockPatternHelper.java index 567cd33a..e2d0850d 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/BlockPatternHelper.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/BlockPatternHelper.java @@ -17,8 +17,9 @@ public class BlockPatternHelper { for (Direction direction : Direction.values()) { for (Direction direction2 : Direction.values()) { BlockPattern.BlockPatternMatch result; - if (direction2 == direction || direction2 == direction.getOpposite() || (result = pattern.matches(blockPos, direction, direction2, loadingCache)) == null) + if (direction2 == direction || direction2 == direction.getOpposite() || (result = pattern.matches(blockPos, direction, direction2, loadingCache)) == null) { continue; + } return result; } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java index 6dd530e7..bc79a7cf 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java @@ -90,7 +90,9 @@ public class ElytraAeronauticsHelper { MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable()); return true; } - if (entity.spawnReason == null) entity.spawnReason = CreatureSpawnEvent.SpawnReason.DEFAULT; + if (entity.spawnReason == null) { + entity.spawnReason = CreatureSpawnEvent.SpawnReason.DEFAULT; + } if (entity.isRemoved()) { return false; } @@ -121,8 +123,8 @@ public class ElytraAeronauticsHelper { serverPlayer.sendSystemMessage(Component.literal(LeavesConfig.modify.elytraAeronautics.startMessage), true); } try { - PlatformHooks.get().removePlayerFromDistanceMaps(serverPlayer.serverLevel(), serverPlayer); - serverPlayer.serverLevel().chunkSource.chunkMap.getDistanceManager().removePlayer(serverPlayer.getLastSectionPos(), serverPlayer); + PlatformHooks.get().removePlayerFromDistanceMaps(serverPlayer.level(), serverPlayer); + serverPlayer.level().chunkSource.chunkMap.getDistanceManager().removePlayer(serverPlayer.getLastSectionPos(), serverPlayer); } catch (Exception ignored) { } } @@ -136,8 +138,8 @@ public class ElytraAeronauticsHelper { serverPlayer.sendSystemMessage(Component.literal(LeavesConfig.modify.elytraAeronautics.endMessage), true); } try { - PlatformHooks.get().addPlayerToDistanceMaps((ServerLevel) serverPlayer.level(), serverPlayer); - ((ServerLevel) serverPlayer.level()).chunkSource.chunkMap.getDistanceManager().addPlayer(SectionPos.of(serverPlayer), serverPlayer); + PlatformHooks.get().addPlayerToDistanceMaps(serverPlayer.level(), serverPlayer); + serverPlayer.level().chunkSource.chunkMap.getDistanceManager().addPlayer(SectionPos.of(serverPlayer), serverPlayer); } catch (Exception ignored) { } } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java index ec5aa65d..588fac5e 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java @@ -3,6 +3,7 @@ package org.leavesmc.leaves.util; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.registries.Registries; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.BlockTags; @@ -35,6 +36,7 @@ public interface FertilizableCoral extends BonemealableBlock { @Override default boolean isBonemealSuccess(@NotNull Level world, RandomSource random, @NotNull BlockPos pos, @NotNull BlockState state) { + ((ServerLevel) world).sendParticles(ParticleTypes.HAPPY_VILLAGER, pos.getX() + 0.5, pos.getY() + 1.0, pos.getZ() + 0.5, 8, 0.3, 0.5, 0.3, 0.0); return random.nextFloat() < 0.15D; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/ForcePeacefulModeSwitchType.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/ForcePeacefulModeSwitchType.java deleted file mode 100644 index d8d577dc..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/ForcePeacefulModeSwitchType.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.leavesmc.leaves.util; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.monster.*; -import net.minecraft.world.entity.monster.breeze.Breeze; -import net.minecraft.world.entity.monster.hoglin.Hoglin; -import net.minecraft.world.entity.monster.piglin.Piglin; -import net.minecraft.world.entity.monster.piglin.PiglinBrute; -import net.minecraft.world.entity.monster.warden.Warden; -import net.minecraft.world.entity.boss.wither.WitherBoss; - -public enum ForcePeacefulModeSwitchType { - BLAZE(Blaze.class), - CREEPER(Creeper.class), - DROWNED(Drowned.class), - ELDER_GUARDIAN(ElderGuardian.class), - ENDERMAN(EnderMan.class), - ENDERMITE(Endermite.class), - EVOKER(Evoker.class), - GHAST(Ghast.class), - GIANT(Giant.class), - GUARDIAN(Guardian.class), - HOGLIN(Hoglin.class), - HUSK(Husk.class), - ILLUSIONER(Illusioner.class), - MAGMA_CUBE(MagmaCube.class), - PHANTOM(Phantom.class), - PIGLIN(Piglin.class), - PIGLIN_BRUTE(PiglinBrute.class), - PILLAGER(Pillager.class), - RAVAGER(Ravager.class), - SHULKER(Shulker.class), - SILVERFISH(Silverfish.class), - SKELETON(Skeleton.class), - SLIME(Slime.class), - SPIDER(Spider.class), - STRAY(Stray.class), - VEX(Vex.class), - VINDICATOR(Vindicator.class), - WARDEN(Warden.class), - WITCH(Witch.class), - WITHER_SKELETON(WitherSkeleton.class), - ZOGLIN(Zoglin.class), - ZOMBIE(Zombie.class), - ZOMBIE_VILLAGER(ZombieVillager.class), - ZOMBIFIED_PIGLIN(ZombifiedPiglin.class), - WITHER(WitherBoss.class), - CAVE_SPIDER(CaveSpider.class), - BREEZE(Breeze.class), - BOGGED(Bogged.class); - - private final Class entityClass; - - ForcePeacefulModeSwitchType(Class entityClass) { - this.entityClass = entityClass; - } - - public Class getEntityClass() { - return entityClass; - } -} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/HopperCounter.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/HopperCounter.java index 83fe0ead..2dac5712 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/HopperCounter.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/HopperCounter.java @@ -314,9 +314,15 @@ public class HopperCounter { int r = (color >> 16 & 255); int g = (color >> 8 & 255); int b = (color & 255); - if (r < 70) r = 70; - if (g < 70) g = 70; - if (b < 70) b = 70; + if (r < 70) { + r = 70; + } + if (g < 70) { + g = 70; + } + if (b < 70) { + b = 70; + } return (r << 16) + (g << 8) + b; } diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java new file mode 100644 index 00000000..5fa79445 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java @@ -0,0 +1,210 @@ +package org.leavesmc.leaves.util; + +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.ItemContainerContents; +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.Enchantments; +import net.minecraft.world.item.enchantment.ItemEnchantments; +import net.minecraft.world.level.block.ShulkerBoxBlock; +import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesConfig; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public class ItemOverstackUtils { + + private static final List overstackUtils = List.of( + new ShulkerBox(), + new CurseEnchantedBook() + ); + + public static int getItemStackMaxCount(ItemStack stack) { + int size; + for (ItemUtil util : overstackUtils) { + if ((size = util.getMaxServerStackCount(stack)) != -1) { + return size; + } + } + return stack.getMaxStackSize(); + } + + public static int getNetworkMaxCount(ItemStack stack) { + int size; + for (ItemUtil util : overstackUtils) { + if ((size = util.getMaxClientStackCount(stack)) != -1) { + return size; + } + } + return stack.getMaxStackSize(); + } + + public static boolean tryStackItems(ItemEntity self, ItemEntity other) { + for (ItemUtil util : overstackUtils) { + if (util.tryStackItems(self, other)) { + return true; + } + } + return false; + } + + public static boolean hasOverstackingItem() { + return overstackUtils.stream().anyMatch(ItemUtil::isEnabled); + } + + public static int getItemStackMaxCountReal(ItemStack stack) { + CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag(); + return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize()); + } + + public static ItemStack encodeMaxStackSize(ItemStack itemStack) { + int realMaxStackSize = getItemStackMaxCountReal(itemStack); + int modifiedMaxStackSize = getNetworkMaxCount(itemStack); + if (itemStack.getMaxStackSize() != modifiedMaxStackSize) { + itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize); + CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); + nbt.putInt("Leaves.RealStackSize", realMaxStackSize); + itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt)); + } + return itemStack; + } + + public static ItemStack decodeMaxStackSize(ItemStack itemStack) { + int realMaxStackSize = getItemStackMaxCountReal(itemStack); + if (itemStack.getMaxStackSize() != realMaxStackSize) { + itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize); + CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); + nbt.remove("Leaves.RealStackSize"); + if (nbt.isEmpty()) { + itemStack.remove(DataComponents.CUSTOM_DATA); + } else { + itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt)); + } + } + return itemStack; + } + + public static boolean isStackable(ItemStack itemStack) { + return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged()); + } + + + private interface ItemUtil { + boolean isEnabled(); + + boolean tryStackItems(ItemEntity self, ItemEntity other); + + // number -> modified count, -1 -> I don't care + int getMaxServerStackCount(ItemStack stack); + + // number -> modified count, -1 -> I don't care + default int getMaxClientStackCount(ItemStack stack) { + return getMaxServerStackCount(stack); + } + } + + private static class ShulkerBox implements ItemUtil { + @Override + public boolean isEnabled() { + return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize > 1; + } + + @Override + public boolean tryStackItems(ItemEntity self, ItemEntity other) { + ItemStack selfStack = self.getItem(); + if (!isEnabled() || + !(selfStack.getItem() instanceof net.minecraft.world.item.BlockItem blockItem) || + !(blockItem.getBlock() instanceof net.minecraft.world.level.block.ShulkerBoxBlock) + ) { + return false; + } + + ItemStack otherStack = other.getItem(); + if (selfStack.getItem() == otherStack.getItem() + && shulkerBoxCheck(selfStack, otherStack) + && selfStack.getCount() != org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.shulkerBoxStackSize) { + int amount = Math.min(otherStack.getCount(), org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.shulkerBoxStackSize - selfStack.getCount()); + + selfStack.grow(amount); + self.setItem(selfStack); + + self.pickupDelay = Math.max(other.pickupDelay, self.pickupDelay); + self.age = Math.min(other.getAge(), self.age); + + otherStack.shrink(amount); + if (otherStack.isEmpty()) { + other.discard(); + } else { + other.setItem(otherStack); + } + return true; + } + return false; + } + + @Override + public int getMaxServerStackCount(ItemStack stack) { + if (isEnabled() && stack.getItem() instanceof BlockItem bi && + bi.getBlock() instanceof ShulkerBoxBlock && (LeavesConfig.modify.shulkerBox.sameNbtStackable || shulkerBoxNoItem(stack))) { + return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize; + } + return -1; + } + + public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) { + if (LeavesConfig.modify.shulkerBox.sameNbtStackable) { + return Objects.equals(stack1.getComponents(), stack2.getComponents()); + } + return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents()); + } + + public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) { + return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty(); + } + } + + public static class CurseEnchantedBook implements ItemUtil { + private static final MappedRegistry registry = (MappedRegistry) MinecraftServer.getServer().registryAccess().lookup(Registries.ENCHANTMENT).orElseThrow(); + + @Override + public boolean isEnabled() { + return LeavesConfig.modify.oldMC.allowGrindstoneOverstacking; + } + + @Override + public boolean tryStackItems(ItemEntity self, ItemEntity other) { + return false; + } + + @Override + public int getMaxServerStackCount(ItemStack stack) { + return -1; + } + + @Override + public int getMaxClientStackCount(ItemStack stack) { + if (isEnabled() && isCursedEnchantedBook(stack)) { + return 2; + } + return -1; + } + + public static boolean isCursedEnchantedBook(ItemStack stack) { + ItemEnchantments enchantments = stack.getOrDefault(DataComponents.STORED_ENCHANTMENTS, ItemEnchantments.EMPTY); + if (enchantments.size() != 1) { + return false; + } + return enchantments.getLevel(registry.getOrThrow(Enchantments.BINDING_CURSE)) == 1 || + enchantments.getLevel(registry.getOrThrow(Enchantments.VANISHING_CURSE)) == 1; + } + } +} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/ServerI18nUtil.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/ServerI18nUtil.java index b6a3b79d..11bbe3fd 100644 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/ServerI18nUtil.java +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/ServerI18nUtil.java @@ -42,7 +42,7 @@ import java.util.regex.Pattern; public class ServerI18nUtil { private static final Logger logger = LogUtils.getClassLogger(); - private static final String VERSION = DetectedVersion.BUILT_IN.getName(); + private static final String VERSION = DetectedVersion.BUILT_IN.name(); private static final String BASE_PATH = "cache/leaves/" + VERSION + "/"; private static final String defaultLeavesLangPath = "/assets/leaves/lang/en_us.json"; private static final String manifestUrl = "https://launchermeta.mojang.com/mc/game/version_manifest.json"; diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/ShulkerBoxUtils.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/ShulkerBoxUtils.java deleted file mode 100644 index a0227fad..00000000 --- a/leaves-server/src/main/java/org/leavesmc/leaves/util/ShulkerBoxUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.leavesmc.leaves.util; - -import net.minecraft.core.component.DataComponents; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.CustomData; -import net.minecraft.world.item.component.ItemContainerContents; -import net.minecraft.world.level.block.ShulkerBoxBlock; -import org.jetbrains.annotations.NotNull; -import org.leavesmc.leaves.LeavesConfig; - -import java.util.Optional; - -public class ShulkerBoxUtils { - - public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) { - return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty(); - } - - public static int getItemStackMaxCount(ItemStack stack) { - if (LeavesConfig.modify.shulkerBoxStackSize > 1 && stack.getItem() instanceof BlockItem bi && - bi.getBlock() instanceof ShulkerBoxBlock && shulkerBoxNoItem(stack)) { - return LeavesConfig.modify.shulkerBoxStackSize; - } - return stack.getMaxStackSize(); - } - - public static int getItemStackMaxCountReal(ItemStack stack) { - CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag(); - return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize()); - } - - public static ItemStack encodeMaxStackSize(ItemStack itemStack) { - int realMaxStackSize = getItemStackMaxCountReal(itemStack); - int modifiedMaxStackSize = getItemStackMaxCount(itemStack); - if (itemStack.getMaxStackSize() != modifiedMaxStackSize) { - itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize); - CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); - nbt.putInt("Leaves.RealStackSize", realMaxStackSize); - itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt)); - } - return itemStack; - } - - public static ItemStack decodeMaxStackSize(ItemStack itemStack) { - int realMaxStackSize = getItemStackMaxCountReal(itemStack); - if (itemStack.getMaxStackSize() != realMaxStackSize) { - itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize); - CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag(); - nbt.remove("Leaves.RealStackSize"); - if (nbt.isEmpty()) { - itemStack.remove(DataComponents.CUSTOM_DATA); - } else { - itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt)); - } - } - return itemStack; - } - - public static boolean isStackable(ItemStack itemStack) { - return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged()); - } -} \ No newline at end of file diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/TagFactory.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/TagFactory.java new file mode 100644 index 00000000..7e69073e --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/TagFactory.java @@ -0,0 +1,29 @@ +package org.leavesmc.leaves.util; + +import net.minecraft.core.RegistryAccess; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ProblemReporter; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; + +public class TagFactory { + + private static final RegistryAccess.Frozen registryAccess = MinecraftServer.getServer().registryAccess(); + + public static TagValueOutput output() { + return TagValueOutput.createWithContext(ProblemReporter.DISCARDING, registryAccess); + } + + public static TagValueOutput output(CompoundTag tag) { + return TagValueOutput.createWrappingWithContext(ProblemReporter.DISCARDING, registryAccess, tag); + } + + public static TagValueInput input() { + return input(new CompoundTag()); + } + + public static TagValueInput input(CompoundTag tag) { + return (TagValueInput) TagValueInput.create(ProblemReporter.DISCARDING, registryAccess, tag); + } +} diff --git a/leaves-server/src/main/java/org/leavesmc/leaves/util/TagUtil.java b/leaves-server/src/main/java/org/leavesmc/leaves/util/TagUtil.java new file mode 100644 index 00000000..63e80045 --- /dev/null +++ b/leaves-server/src/main/java/org/leavesmc/leaves/util/TagUtil.java @@ -0,0 +1,71 @@ +package org.leavesmc.leaves.util; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; +import org.jetbrains.annotations.Nullable; + +public class TagUtil { + + public static CompoundTag saveEntity(@Nullable Entity entity) { + if (entity == null) { + return new CompoundTag(); + } + TagValueOutput output = TagFactory.output(); + entity.save(output); + return output.buildResult(); + } + + public static boolean saveEntity(Entity entity, CompoundTag tag) { + if (entity == null) { + return false; + } + TagValueOutput output = TagFactory.output(tag); + return entity.save(output); + } + + public static CompoundTag saveEntityWithoutId(Entity entity) { + if (entity == null) { + return new CompoundTag(); + } + TagValueOutput output = TagFactory.output(); + entity.saveWithoutId(output); + return output.buildResult(); + } + + public static CompoundTag saveTileWithId(@Nullable BlockEntity entity) { + if (entity == null) { + return new CompoundTag(); + } + TagValueOutput output = TagFactory.output(); + entity.saveWithId(output); + return output.buildResult(); + } + + public static boolean saveEntityAsPassenger(@Nullable Entity entity, CompoundTag tag) { + if (entity == null) { + return false; + } + TagValueOutput output = TagFactory.output(tag); + return entity.saveAsPassenger(output); + } + + public static void loadEntity(Entity entity, CompoundTag tag) { + if (entity == null) { + return; + } + TagValueInput input = TagFactory.input(tag); + entity.load(input); + } + + public static void loadTileWithComponents(BlockEntity entity, CompoundTag tag) { + if (entity == null) { + return; + } + TagValueInput input = TagFactory.input(tag); + entity.loadWithComponents(input); + } + +}