diff --git a/build-data/paper.at b/build-data/paper.at index 494df2d8b..f7bc3ced1 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -17,13 +17,8 @@ public net.minecraft.commands.arguments.blocks.BlockInput tag public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V public net.minecraft.nbt.ListTag (Ljava/util/List;)V public net.minecraft.nbt.ListTag identifyRawElementType()B -public net.minecraft.nbt.TagParser readArrayTag()Lnet/minecraft/nbt/Tag; -public net.minecraft.nbt.TagParser type(Ljava/lang/String;)Lnet/minecraft/nbt/Tag; public net.minecraft.network.Connection address public net.minecraft.network.Connection channel -public net.minecraft.network.chat.HoverEvent$ItemStackInfo components -public net.minecraft.network.chat.HoverEvent$ItemStackInfo count -public net.minecraft.network.chat.HoverEvent$ItemStackInfo item public net.minecraft.network.chat.TextColor name public net.minecraft.network.chat.contents.TranslatableContents filterAllowedArguments(Ljava/lang/Object;)Lcom/mojang/serialization/DataResult; public net.minecraft.network.chat.numbers.FixedFormat value @@ -108,14 +103,12 @@ public net.minecraft.server.level.ServerPlayer triggerDimensionChangeTriggers(Ln public net.minecraft.server.level.ServerPlayer wardenSpawnTracker public net.minecraft.server.level.ServerPlayer$RespawnPosAngle public net.minecraft.server.level.ServerPlayerGameMode level -public net.minecraft.server.level.Ticket key public net.minecraft.server.level.TicketType register(Ljava/lang/String;JZLnet/minecraft/server/level/TicketType$TicketUse;)Lnet/minecraft/server/level/TicketType; public net.minecraft.server.network.ServerGamePacketListenerImpl isChatMessageIllegal(Ljava/lang/String;)Z public net.minecraft.server.network.ServerLoginPacketListenerImpl authenticatedProfile public net.minecraft.server.network.ServerLoginPacketListenerImpl connection public net.minecraft.server.network.ServerLoginPacketListenerImpl state public net.minecraft.server.network.ServerLoginPacketListenerImpl$State -public net.minecraft.server.packs.VanillaPackResourcesBuilder safeGetPath(Ljava/net/URI;)Ljava/nio/file/Path; public net.minecraft.server.packs.repository.FolderRepositorySource$FolderPackDetector public net.minecraft.server.packs.repository.FolderRepositorySource$FolderPackDetector (Lnet/minecraft/world/level/validation/DirectoryValidator;)V public net.minecraft.server.packs.repository.Pack resources @@ -129,7 +122,6 @@ public net.minecraft.tags.TagEntry id public net.minecraft.tags.TagEntry required public net.minecraft.tags.TagEntry tag public net.minecraft.util.datafix.fixes.BlockStateData register(ILcom/mojang/serialization/Dynamic;[Lcom/mojang/serialization/Dynamic;)V -public net.minecraft.util.datafix.fixes.EntityCustomNameToComponentFix fixCustomName(Lcom/mojang/serialization/DynamicOps;Ljava/lang/String;Ljava/lang/String;)Lcom/mojang/serialization/Dynamic; public net.minecraft.util.datafix.fixes.ItemIdFix ITEM_NAMES public net.minecraft.util.datafix.fixes.ItemSpawnEggFix ID_TO_ENTITY public net.minecraft.world.BossEvent color @@ -138,6 +130,11 @@ public net.minecraft.world.BossEvent overlay public net.minecraft.world.CompoundContainer container1 public net.minecraft.world.CompoundContainer container2 public net.minecraft.world.SimpleContainer items +public net.minecraft.world.damagesource.CombatTracker entries +public net.minecraft.world.damagesource.CombatTracker getMostSignificantFall()Lnet/minecraft/world/damagesource/CombatEntry; +public net.minecraft.world.damagesource.CombatTracker inCombat +public net.minecraft.world.damagesource.CombatTracker mob +public net.minecraft.world.damagesource.CombatTracker takingDamage public net.minecraft.world.damagesource.DamageSource (Lnet/minecraft/core/Holder;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;)V public net.minecraft.world.effect.MobEffect attributeModifiers public net.minecraft.world.effect.MobEffect$AttributeTemplate @@ -198,7 +195,6 @@ public net.minecraft.world.entity.Entity getSwimSound()Lnet/minecraft/sounds/Sou public net.minecraft.world.entity.Entity getSwimSplashSound()Lnet/minecraft/sounds/SoundEvent; public net.minecraft.world.entity.Entity hasVisualFire public net.minecraft.world.entity.Entity isAffectedByBlocks()Z -public net.minecraft.world.entity.Entity isInBubbleColumn()Z public net.minecraft.world.entity.Entity isInRain()Z public net.minecraft.world.entity.Entity isInvulnerableToBase(Lnet/minecraft/world/damagesource/DamageSource;)Z public net.minecraft.world.entity.Entity onGround @@ -213,7 +209,6 @@ public net.minecraft.world.entity.Entity unsetRemoved()V public net.minecraft.world.entity.Entity wasTouchingWater public net.minecraft.world.entity.ExperienceOrb count public net.minecraft.world.entity.ExperienceOrb setValue(I)V -public net.minecraft.world.entity.ExperienceOrb value public net.minecraft.world.entity.GlowSquid setDarkTicks(I)V public net.minecraft.world.entity.Interaction attack public net.minecraft.world.entity.Interaction getHeight()F @@ -248,14 +243,10 @@ public net.minecraft.world.entity.LivingEntity lastHurtByMob public net.minecraft.world.entity.LivingEntity lastHurtByMobTimestamp public net.minecraft.world.entity.LivingEntity lastHurtByPlayer public net.minecraft.world.entity.LivingEntity lastHurtByPlayerMemoryTime -public net.minecraft.world.entity.LivingEntity lastHurtByPlayerTime public net.minecraft.world.entity.LivingEntity playSecondaryHurtSound(Lnet/minecraft/world/damagesource/DamageSource;)V public net.minecraft.world.entity.LivingEntity setLivingEntityFlag(IZ)V public net.minecraft.world.entity.LivingEntity useItemRemaining -public net.minecraft.world.entity.Mob armorDropChances public net.minecraft.world.entity.Mob getAmbientSound()Lnet/minecraft/sounds/SoundEvent; -public net.minecraft.world.entity.Mob getEquipmentDropChance(Lnet/minecraft/world/entity/EquipmentSlot;)F -public net.minecraft.world.entity.Mob handDropChances public net.minecraft.world.entity.Mob isSunBurnTick()Z public net.minecraft.world.entity.Mob lootTable public net.minecraft.world.entity.Mob lootTableSeed @@ -431,7 +422,6 @@ public net.minecraft.world.entity.npc.Villager setUnhappy()V public net.minecraft.world.entity.npc.WanderingTrader getWanderTarget()Lnet/minecraft/core/BlockPos; public net.minecraft.world.entity.player.Abilities flyingSpeed public net.minecraft.world.entity.player.Abilities walkingSpeed -public net.minecraft.world.entity.player.Inventory compartments public net.minecraft.world.entity.player.Inventory equipment public net.minecraft.world.entity.player.Player DATA_PLAYER_MODE_CUSTOMISATION public net.minecraft.world.entity.player.Player closeContainer()V @@ -492,7 +482,6 @@ public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaY public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaZ public net.minecraft.world.entity.projectile.SpectralArrow duration public net.minecraft.world.entity.projectile.ThrowableItemProjectile getDefaultItem()Lnet/minecraft/world/item/Item; -public net.minecraft.world.entity.projectile.ThrownPotion isLingering()Z public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage public net.minecraft.world.entity.projectile.windcharge.AbstractWindCharge explode(Lnet/minecraft/world/phys/Vec3;)V public net.minecraft.world.entity.projectile.windcharge.BreezeWindCharge explode(Lnet/minecraft/world/phys/Vec3;)V @@ -522,6 +511,7 @@ public net.minecraft.world.flag.FeatureFlagRegistry names public net.minecraft.world.food.FoodData exhaustionLevel public net.minecraft.world.food.FoodData foodLevel public net.minecraft.world.food.FoodData saturationLevel +public net.minecraft.world.inventory.AbstractContainerMenu menuType public net.minecraft.world.inventory.AbstractContainerMenu quickcraftSlots public net.minecraft.world.inventory.AbstractContainerMenu quickcraftStatus public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType @@ -558,7 +548,6 @@ public net.minecraft.world.item.context.UseOnContext (Lnet/minecraft/world public net.minecraft.world.item.crafting.RecipeManager recipes public net.minecraft.world.item.crafting.RecipeMap byKey public net.minecraft.world.item.crafting.RecipeMap byType -public net.minecraft.world.item.enchantment.ItemEnchantments showInTooltip public net.minecraft.world.item.trading.MerchantOffer demand public net.minecraft.world.item.trading.MerchantOffer result public net.minecraft.world.item.trading.MerchantOffer specialPriceDiff @@ -777,7 +766,6 @@ public-f net.minecraft.world.inventory.AbstractContainerMenu lastSlots public-f net.minecraft.world.inventory.AbstractContainerMenu remoteDataSlots public-f net.minecraft.world.inventory.AbstractContainerMenu remoteSlots public-f net.minecraft.world.inventory.AbstractContainerMenu slots -public-f net.minecraft.world.item.enchantment.ItemEnchantments$Mutable showInTooltip public-f net.minecraft.world.item.trading.MerchantOffer baseCostA public-f net.minecraft.world.item.trading.MerchantOffer costB public-f net.minecraft.world.item.trading.MerchantOffer maxUses diff --git a/build.gradle.kts b/build.gradle.kts index 42b17e13e..dce699b6b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { - id("io.papermc.paperweight.core") version "2.0.0-beta.16" apply false + id("io.papermc.paperweight.core") version "2.0.0-beta.17" apply false } subprojects { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b953..1b33c55ba 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 cea7a793a..ca025c83a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ 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-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f3b75f3b0..23d15a936 100755 --- a/gradlew +++ b/gradlew @@ -114,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. @@ -205,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. @@ -213,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 9d21a2183..db3a6ac20 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/paper-api/build.gradle.kts b/paper-api/build.gradle.kts index 849380593..82d300591 100644 --- a/paper-api/build.gradle.kts +++ b/paper-api/build.gradle.kts @@ -11,8 +11,7 @@ java { val annotationsVersion = "26.0.2" // Keep in sync with paper-server adventure-text-serializer-ansi dep -val adventureVersion = "4.21.0-mc1215-SNAPSHOT" // FIXME move to release asap -val adventureJavadocVersion = "4.20.0" // Fixme remove me +val adventureVersion = "4.21.0" val bungeeCordChatVersion = "1.21-R0.2-deprecated+build.21" val slf4jVersion = "2.0.16" val log4jVersion = "2.24.1" @@ -58,15 +57,13 @@ dependencies { exclude("com.google.guava", "guava") } - // FIXME remove me when we are using a release again - val adventureGroup = "io.papermc.adventure" - apiAndDocs(platform("$adventureGroup:adventure-bom:$adventureVersion")) - apiAndDocs("$adventureGroup:adventure-api") - apiAndDocs("$adventureGroup:adventure-text-minimessage") - apiAndDocs("$adventureGroup:adventure-text-serializer-gson") - apiAndDocs("$adventureGroup:adventure-text-serializer-legacy") - apiAndDocs("$adventureGroup:adventure-text-serializer-plain") - apiAndDocs("$adventureGroup:adventure-text-logger-slf4j") + apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion")) + apiAndDocs("net.kyori:adventure-api") + apiAndDocs("net.kyori:adventure-text-minimessage") + apiAndDocs("net.kyori:adventure-text-serializer-gson") + apiAndDocs("net.kyori:adventure-text-serializer-legacy") + apiAndDocs("net.kyori:adventure-text-serializer-plain") + apiAndDocs("net.kyori:adventure-text-logger-slf4j") api("org.apache.maven:maven-resolver-provider:3.9.6") // make API dependency for Paper Plugins compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") @@ -179,13 +176,13 @@ tasks.withType { "https://javadoc.io/doc/org.joml/joml/1.10.8/", "https://www.javadoc.io/doc/com.google.code.gson/gson/2.11.0", "https://jspecify.dev/docs/api/", - "https://jd.advntr.dev/api/$adventureJavadocVersion/", - "https://jd.advntr.dev/key/$adventureJavadocVersion/", - "https://jd.advntr.dev/text-minimessage/$adventureJavadocVersion/", - "https://jd.advntr.dev/text-serializer-gson/$adventureJavadocVersion/", - "https://jd.advntr.dev/text-serializer-legacy/$adventureJavadocVersion/", - "https://jd.advntr.dev/text-serializer-plain/$adventureJavadocVersion/", - "https://jd.advntr.dev/text-logger-slf4j/$adventureJavadocVersion/", + "https://jd.advntr.dev/api/$adventureVersion/", + "https://jd.advntr.dev/key/$adventureVersion/", + "https://jd.advntr.dev/text-minimessage/$adventureVersion/", + "https://jd.advntr.dev/text-serializer-gson/$adventureVersion/", + "https://jd.advntr.dev/text-serializer-legacy/$adventureVersion/", + "https://jd.advntr.dev/text-serializer-plain/$adventureVersion/", + "https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/", "https://javadoc.io/doc/org.slf4j/slf4j-api/$slf4jVersion/", "https://logging.apache.org/log4j/2.x/javadoc/log4j-api/", "https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3", diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java index ae7291697..406389cf2 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java @@ -27,7 +27,9 @@ public class EndermanEscapeEvent extends EntityEvent implements Cancellable { } /** - * @return The reason the enderman is trying to escape + * Gets the reason the enderman is trying to escape. + * + * @return The reason */ public Reason getReason() { return this.reason; @@ -42,7 +44,8 @@ public class EndermanEscapeEvent extends EntityEvent implements Cancellable { * Cancels the escape. *

* If this escape normally had resulted in damage avoidance such as indirect, - * the enderman will now take damage. + * the enderman will now take damage. However, this does not change the Enderman's + * innate immunities or damage behavior like arrows where the damage never happens. */ @Override public void setCancelled(final boolean cancel) { @@ -76,7 +79,7 @@ public class EndermanEscapeEvent extends EntityEvent implements Cancellable { */ STARE, /** - * Specific case for {@link #CRITICAL_HIT} where the enderman is taking rain damage + * Specific case for {@link #CRITICAL_HIT} where the enderman is taking damage by drowning (ex: rain) */ DROWN } diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java index e82446ec3..663341958 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerPostRespawnEvent.java @@ -1,9 +1,10 @@ package com.destroystokyo.paper.event.player; +import io.papermc.paper.event.player.AbstractRespawnEvent; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerRespawnEvent; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -11,36 +12,31 @@ import org.jspecify.annotations.NullMarked; * Fired after a player has respawned */ @NullMarked -public class PlayerPostRespawnEvent extends PlayerEvent { +public class PlayerPostRespawnEvent extends AbstractRespawnEvent { private static final HandlerList HANDLER_LIST = new HandlerList(); - private final Location respawnedLocation; - private final boolean isBedSpawn; - @ApiStatus.Internal - public PlayerPostRespawnEvent(final Player respawnPlayer, final Location respawnedLocation, final boolean isBedSpawn) { - super(respawnPlayer); - this.respawnedLocation = respawnedLocation; - this.isBedSpawn = isBedSpawn; + public PlayerPostRespawnEvent( + final Player respawnPlayer, + final Location respawnLocation, + final boolean isBedSpawn, + final boolean isAnchorSpawn, + final boolean missingRespawnBlock, + final PlayerRespawnEvent.RespawnReason respawnReason + ) { + super(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, missingRespawnBlock, respawnReason); } /** - * Returns the location of the respawned player + * Returns the location of the respawned player. * * @return location of the respawned player + * @see #getRespawnLocation() */ + @ApiStatus.Obsolete public Location getRespawnedLocation() { - return this.respawnedLocation.clone(); - } - - /** - * Checks if the player respawned to their bed - * - * @return whether the player respawned to their bed - */ - public boolean isBedSpawn() { - return this.isBedSpawn; + return super.getRespawnLocation(); } @Override diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java index 0482ecf5b..c56aa35dd 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java @@ -119,7 +119,7 @@ public class AsyncTabCompleteEvent extends Event implements Cancellable { * the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])} * or current player names will not be called. *

- * The passed collection will be cloned to a new {@code List}. You must call {{@link #getCompletions()}} to mutate from here + * The passed collection will be cloned to a new {@code List}. You must call {@link #getCompletions()} to mutate from here * * @param completions the new completions */ diff --git a/paper-api/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/paper-api/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java index 023cc52a9..da46e2b17 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java @@ -21,12 +21,24 @@ public interface VersionFetcher { /** * Gets the version message to cache and show to command senders. * - *

NOTE: This is run in a new thread separate from that of the command processing thread

+ * @return the message to show when requesting a version + * @apiNote This method may involve a web request which will block the executing thread + */ + Component getVersionMessage(); + + /** + * Gets the version message to cache and show to command senders. * * @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()}) * @return the message to show when requesting a version + * @apiNote This method may involve a web request which will block the current thread + * @see #getVersionMessage() + * @deprecated {@code serverVersion} is not required */ - Component getVersionMessage(String serverVersion); + @Deprecated + default Component getVersionMessage(String serverVersion) { + return getVersionMessage(); + } @ApiStatus.Internal class DummyVersionFetcher implements VersionFetcher { @@ -37,7 +49,7 @@ public interface VersionFetcher { } @Override - public Component getVersionMessage(final String serverVersion) { + public Component getVersionMessage() { Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!"); Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()"); new Throwable().printStackTrace(); diff --git a/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java b/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java index 861c42cbf..422fdd93d 100644 --- a/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java +++ b/paper-api/src/main/java/io/papermc/paper/InternalAPIBridge.java @@ -1,10 +1,15 @@ package io.papermc.paper; +import io.papermc.paper.world.damagesource.CombatEntry; +import io.papermc.paper.world.damagesource.FallLocationType; import net.kyori.adventure.util.Services; import org.bukkit.block.Biome; import org.bukkit.damage.DamageEffect; +import org.bukkit.damage.DamageSource; +import org.bukkit.entity.LivingEntity; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Static bridge to the server internals. @@ -45,5 +50,28 @@ public interface InternalAPIBridge { @Deprecated(forRemoval = true, since = "1.21.5") @ApiStatus.ScheduledForRemoval(inVersion = "1.22") Biome constructLegacyCustomBiome(); + + /** + * Creates a new combat entry. + *

+ * The fall location and fall distance will be calculated from the entity's current state. + * + * @param entity entity + * @param damageSource damage source + * @param damage damage amount + * @return new combat entry + */ + CombatEntry createCombatEntry(LivingEntity entity, DamageSource damageSource, float damage); + + /** + * Creates a new combat entry + * + * @param damageSource damage source + * @param damage damage amount + * @param fallLocationType fall location type + * @param fallDistance fall distance + * @return combat entry + */ + CombatEntry createCombatEntry(DamageSource damageSource, float damage, @Nullable FallLocationType fallLocationType, float fallDistance); } diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java index 7e1d500b1..3d7429d7e 100644 --- a/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java @@ -15,5 +15,9 @@ public enum CommandRegistrationFlag { * @deprecated This is the default behavior now. */ @Deprecated(since = "1.21.4") - FLATTEN_ALIASES + FLATTEN_ALIASES, + /** + * Prevents this command from being sent to the client. + */ + SERVER_ONLY } diff --git a/paper-api/src/main/java/io/papermc/paper/configuration/ServerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/configuration/ServerConfiguration.java new file mode 100644 index 000000000..86d1b609b --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/configuration/ServerConfiguration.java @@ -0,0 +1,24 @@ +package io.papermc.paper.configuration; + +/** + * Represents the configuration settings for a server. + *

+ * This interface doesn't aim to cover every possible server configuration + * option but focuses on selected critical settings and behaviors. + */ +public interface ServerConfiguration { + + /** + * Gets whether the server is in online mode. + *

+ * This method returns true if: + *

    + *
  • The server is in {@link org.bukkit.Server#getOnlineMode online mode},
  • + *
  • Velocity is enabled and configured to be in online mode, or
  • + *
  • BungeeCord is enabled and configured to be in online mode.
  • + *
+ * + * @return whether the server is in online mode or behind a proxy configured for online mode + */ + boolean isProxyOnlineMode(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java index bf53d0e0b..d7372673a 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java @@ -1,6 +1,8 @@ package io.papermc.paper.datacomponent.item; import io.papermc.paper.datacomponent.DataComponentBuilder; +import io.papermc.paper.datacomponent.item.blocksattacks.DamageReduction; +import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction; import io.papermc.paper.registry.tag.TagKey; import net.kyori.adventure.key.Key; import org.bukkit.damage.DamageType; @@ -8,8 +10,13 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; +import java.util.List; -// TODO +/** + * Holds block attacks to the holding player like Shield. + * + * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS + */ @NullMarked @ApiStatus.Experimental @ApiStatus.NonExtendable @@ -20,19 +27,59 @@ public interface BlocksAttacks { return ItemComponentTypesBridge.bridge().blocksAttacks(); } + /** + * Gets the amount of time (in seconds) that use must be held before successfully blocking attacks. + * + * @return the delay in seconds + */ float blockDelaySeconds(); + /** + * Gets the multiplier applied to the cooldown time for the item when attacked by a disabling attack (the multiplier for {@link Weapon#disableBlockingForSeconds()}). + *
+ * If set to 0, this item can never be disabled by attacks. + * + * @return the multiplier for the cooldown time + */ float disableCooldownScale(); - //List damageReductions(); + /** + * Gets a list of {@link DamageReduction} of how much damage should be blocked in a given attack. + * + * @return a list of damage reductions + */ + List damageReductions(); - //ItemDamageFunction itemDamage(); + /** + * Gets how much damage should be applied to the item from a given attack. + * + * @return the damage function + */ + ItemDamageFunction itemDamage(); - @Nullable TagKey bypassedBy(); + /** + * Gets the DamageType that can bypass the blocking. + * + * @return a damage type tag key, or null if there is no such tag key + */ + @Nullable + TagKey bypassedBy(); - @Nullable Key blockSound(); + /** + * Gets the key sound to play when an attack is successfully blocked. + * + * @return a key of the sound + */ + @Nullable + Key blockSound(); - @Nullable Key disableSound(); + /** + * Gets the key sound to play when the item goes on its disabled cooldown due to an attack. + * + * @return a key of the sound + */ + @Nullable + Key disableSound(); /** * Builder for {@link BlocksAttacks}. @@ -47,14 +94,14 @@ public interface BlocksAttacks { @Contract(value = "_ -> this", mutates = "this") Builder disableCooldownScale(float scale); - //@Contract(value = "_ -> this", mutates = "this") - //Builder addDamageReduction(DamageReduction reduction); + @Contract(value = "_ -> this", mutates = "this") + Builder addDamageReduction(DamageReduction reduction); - //@Contract(value = "_ -> this", mutates = "this") - //Builder damageReductions(List reductions); + @Contract(value = "_ -> this", mutates = "this") + Builder damageReductions(List reductions); - //@Contract(value = "_ -> this", mutates = "this") - //Builder itemDamage(ItemDamageFunction function); + @Contract(value = "_ -> this", mutates = "this") + Builder itemDamage(ItemDamageFunction function); @Contract(value = "_ -> this", mutates = "this") Builder bypassedBy(@Nullable TagKey bypassedBy); diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java index 1583d4083..984f793a4 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/PotionContents.java @@ -60,6 +60,27 @@ public interface PotionContents { @Contract(pure = true) @Nullable String customName(); + /** + * All effects that this component applies. + *

+ * This is a combination of the base potion type and any custom effects. + * + * @return an unmodifiable list of all effects. + */ + @Contract(pure = true) + @Unmodifiable List allEffects(); + + /** + * Computes the effective colour of this potion contents component. + *

+ * This blends all custom effects, or uses a default fallback colour. + * It may or may not have an alpha channel, used for tipped arrows. + * + * @return the effective colour this component would display with. + */ + @Contract(pure = true) + Color computeEffectiveColor(); + @ApiStatus.Experimental @ApiStatus.NonExtendable interface Builder extends DataComponentBuilder { diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridge.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridge.java new file mode 100644 index 000000000..aafc085c9 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridge.java @@ -0,0 +1,21 @@ +package io.papermc.paper.datacomponent.item.blocksattacks; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; +import java.util.Optional; +import java.util.ServiceLoader; + +@NullMarked +@ApiStatus.Internal +interface BlocksAttacksBridge { + + Optional BRIDGE = ServiceLoader.load(BlocksAttacksBridge.class).findFirst(); + + static BlocksAttacksBridge bridge() { + return BRIDGE.orElseThrow(); + } + + DamageReduction.Builder blocksAttacksDamageReduction(); + + ItemDamageFunction.Builder blocksAttacksItemDamageFunction(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/DamageReduction.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/DamageReduction.java new file mode 100644 index 000000000..fbf4a0378 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/DamageReduction.java @@ -0,0 +1,78 @@ +package io.papermc.paper.datacomponent.item.blocksattacks; + +import io.papermc.paper.datacomponent.DataComponentBuilder; +import io.papermc.paper.registry.set.RegistryKeySet; +import org.bukkit.damage.DamageType; +import org.checkerframework.checker.index.qual.Positive; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * Hold how much damage should be blocked in a given attack. + * + * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS + * @see io.papermc.paper.datacomponent.item.BlocksAttacks#damageReductions() + */ +@NullMarked +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface DamageReduction { + + @Contract(value = "-> new", pure = true) + static DamageReduction.Builder damageReduction() { + return BlocksAttacksBridge.bridge().blocksAttacksDamageReduction(); + } + + /** + * The damage types to block. + * + * @return the set of damage type + */ + @Nullable + RegistryKeySet type(); + + /** + * Get the maximum angle between the users facing direction and the direction of the incoming attack to be blocked. + * + * @return the angle + */ + @Positive + float horizontalBlockingAngle(); + + /** + * Get the constant amount of damage to be blocked. + * + * @return the base + */ + float base(); + + /** + * Get the fraction of the dealt damage to be blocked. + * + * @return the factor + */ + float factor(); + + /** + * Builder for {@link DamageReduction}. + */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends DataComponentBuilder { + + @Contract(value = "_ -> this", mutates = "this") + DamageReduction.Builder type(RegistryKeySet type); + + @Contract(value = "_ -> this", mutates = "this") + DamageReduction.Builder horizontalBlockingAngle(@Positive float horizontalBlockingAngle); + + @Contract(value = "_ -> this", mutates = "this") + DamageReduction.Builder base(float base); + + @Contract(value = "_ -> this", mutates = "this") + DamageReduction.Builder factor(float factor); + } + +} diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/ItemDamageFunction.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/ItemDamageFunction.java new file mode 100644 index 000000000..e7301fc1f --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/ItemDamageFunction.java @@ -0,0 +1,71 @@ +package io.papermc.paper.datacomponent.item.blocksattacks; + +import io.papermc.paper.datacomponent.DataComponentBuilder; +import org.checkerframework.checker.index.qual.NonNegative; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * Hold how much damage should be applied to the item from a given attack. + * + * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS + * @see io.papermc.paper.datacomponent.item.BlocksAttacks#itemDamage() + */ +@NullMarked +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface ItemDamageFunction { + + @Contract(value = "-> new", pure = true) + static ItemDamageFunction.Builder itemDamageFunction() { + return BlocksAttacksBridge.bridge().blocksAttacksItemDamageFunction(); + } + + /** + * Get the minimum amount of damage dealt by the attack before item damage is applied to the item. + * + * @return the threshold + */ + @NonNegative + float threshold(); + + /** + * Get the constant amount of damage applied to the item, if threshold is passed. + * + * @return the base + */ + float base(); + + /** + * Get the fraction of the dealt damage that should be applied to the item, if threshold is passed. + * + * @return the factor + */ + float factor(); + + /** + * Get the damage to apply for the item. + * + * @apiNote this doesn't apply enchantments like {@link org.bukkit.enchantments.Enchantment#UNBREAKING} + * @return the damage to apply + */ + int damageToApply(float damage); + + /** + * Builder for {@link ItemDamageFunction}. + */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends DataComponentBuilder { + + @Contract(value = "_ -> this", mutates = "this") + ItemDamageFunction.Builder threshold(@NonNegative final float threshold); + + @Contract(value = "_ -> this", mutates = "this") + ItemDamageFunction.Builder base(final float base); + + @Contract(value = "_ -> this", mutates = "this") + ItemDamageFunction.Builder factor(final float factor); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/FishHookStateChangeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/FishHookStateChangeEvent.java new file mode 100644 index 000000000..dcca23705 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/FishHookStateChangeEvent.java @@ -0,0 +1,52 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.entity.FishHook; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.bukkit.event.player.PlayerFishEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called just before a {@link FishHook}'s {@link FishHook.HookState} is changed. + * + *

If you want to monitor a player's fishing state transition, you can use {@link PlayerFishEvent}.

+ */ +@NullMarked +public final class FishHookStateChangeEvent extends EntityEvent { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final FishHook.HookState newHookState; + + @ApiStatus.Internal + public FishHookStateChangeEvent(final FishHook entity, final FishHook.HookState newHookState) { + super(entity); + this.newHookState = newHookState; + } + + /** + * Get the new hook state of the {@link FishHook}. + * + *

Refer to {@link FishHook#getState()} to get the current hook state.

+ * + * @return the new hook state + */ + public FishHook.HookState getNewHookState() { + return this.newHookState; + } + + @Override + public FishHook getEntity() { + return (FishHook) super.getEntity(); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/packet/UncheckedSignChangeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/packet/UncheckedSignChangeEvent.java new file mode 100644 index 000000000..e36aeb196 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/packet/UncheckedSignChangeEvent.java @@ -0,0 +1,94 @@ +package io.papermc.paper.event.packet; + +import io.papermc.paper.math.BlockPosition; +import io.papermc.paper.math.Position; +import java.util.Collections; +import java.util.List; +import net.kyori.adventure.text.Component; +import org.bukkit.block.sign.Side; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a client attempts to modify a sign, but the location at which the sign should be edited + * has not yet been checked for the existence of a real sign. + *

+ * Cancelling this event will prevent further processing of the sign change, but needs further handling + * by the plugin as the client's local world might be in an inconsistent state. + * + * @see Player#openVirtualSign(Position, Side) + */ +@NullMarked +@ApiStatus.Experimental +public class UncheckedSignChangeEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + private boolean cancel = false; + private final BlockPosition editedBlockPosition; + private final Side side; + private final List lines; + + @ApiStatus.Internal + public UncheckedSignChangeEvent( + final Player editor, + final BlockPosition editedBlockPosition, + final Side side, + final List lines + ) { + super(editor); + this.editedBlockPosition = editedBlockPosition; + this.side = side; + this.lines = lines; + } + + /** + * Gets the location at which a potential sign was edited. + * + * @return location where the change happened + */ + public BlockPosition getEditedBlockPosition() { + return editedBlockPosition; + } + + /** + * Gets which side of the sign was edited. + * + * @return {@link Side} that was edited + */ + public Side getSide() { + return side; + } + + /** + * Gets the lines that the player has entered. + * + * @return the lines + */ + public @Unmodifiable List lines() { + return Collections.unmodifiableList(lines); + } + + @Override + public boolean isCancelled() { + return cancel; + } + + @Override + public void setCancelled(final boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/AbstractRespawnEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/AbstractRespawnEvent.java new file mode 100644 index 000000000..de27fe4ab --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/AbstractRespawnEvent.java @@ -0,0 +1,98 @@ +package io.papermc.paper.event.player; + +import com.google.common.collect.ImmutableSet; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import java.util.Set; + +@NullMarked +public abstract class AbstractRespawnEvent extends PlayerEvent { + + protected Location respawnLocation; + private final boolean isBedSpawn; + private final boolean isAnchorSpawn; + private final boolean missingRespawnBlock; + private final PlayerRespawnEvent.RespawnReason respawnReason; + private final Set respawnFlags; + + protected AbstractRespawnEvent( + final Player respawnPlayer, final Location respawnLocation, final boolean isBedSpawn, + final boolean isAnchorSpawn, final boolean missingRespawnBlock, final PlayerRespawnEvent.RespawnReason respawnReason + ) { + super(respawnPlayer); + this.respawnLocation = respawnLocation; + this.isBedSpawn = isBedSpawn; + this.isAnchorSpawn = isAnchorSpawn; + this.missingRespawnBlock = missingRespawnBlock; + this.respawnReason = respawnReason; + ImmutableSet.Builder builder = ImmutableSet.builder(); + if (respawnReason == PlayerRespawnEvent.RespawnReason.END_PORTAL) builder.add(PlayerRespawnEvent.RespawnFlag.END_PORTAL); + if (this.isBedSpawn) builder.add(PlayerRespawnEvent.RespawnFlag.BED_SPAWN); + if (this.isAnchorSpawn) builder.add(PlayerRespawnEvent.RespawnFlag.ANCHOR_SPAWN); + this.respawnFlags = builder.build(); + } + + /** + * Gets the current respawn location. + * + * @return the current respawn location + */ + public Location getRespawnLocation() { + return this.respawnLocation.clone(); + } + + /** + * Gets whether the respawn location is the player's bed. + * + * @return {@code true} if the respawn location is the player's bed + */ + public boolean isBedSpawn() { + return this.isBedSpawn; + } + + /** + * Gets whether the respawn location is the player's respawn anchor. + * + * @return {@code true} if the respawn location is the player's respawn anchor + */ + public boolean isAnchorSpawn() { + return this.isAnchorSpawn; + } + + /** + * Gets whether the player is missing a valid respawn block. + *

+ * This will occur if the players respawn block is obstructed, + * or it is the first death after it was either destroyed or + * in case of a respawn anchor, ran out of charges. + * + * @return whether the player is missing a valid respawn block + */ + public boolean isMissingRespawnBlock() { + return this.missingRespawnBlock; + } + + /** + * Gets the reason this respawn event was called. + * + * @return the reason the event was called + */ + public PlayerRespawnEvent.RespawnReason getRespawnReason() { + return this.respawnReason; + } + + /** + * Gets the set of flags that apply to this respawn. + * + * @return an immutable set of the flags that apply to this respawn + * @deprecated in favour of {@link #getRespawnReason()}/{@link #isBedSpawn}/{@link #isAnchorSpawn()} + */ + @Deprecated + public @Unmodifiable Set getRespawnFlags() { + return this.respawnFlags; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerMapFilledEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerMapFilledEvent.java new file mode 100644 index 000000000..677125456 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerMapFilledEvent.java @@ -0,0 +1,63 @@ +package io.papermc.paper.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a player creates a filled map by right-clicking an empty map. + */ +@NullMarked +public class PlayerMapFilledEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final ItemStack originalItem; + private ItemStack createdMap; + + @ApiStatus.Internal + public PlayerMapFilledEvent(final Player player, final ItemStack originalItem, final ItemStack createdMap) { + super(player); + this.originalItem = originalItem; + this.createdMap = createdMap; + } + + /** + * Returns a copy of the empty map before it was consumed. + * + * @return cloned original item + */ + public ItemStack getOriginalItem() { + return this.originalItem.clone(); + } + + /** + * Returns a copy of the filled map which was created. + * + * @return cloned created map item + */ + public ItemStack getCreatedMap() { + return this.createdMap.clone(); + } + + /** + * Sets the filled map that will be created. + * + * @param createdMap map item + */ + public void setCreatedMap(final ItemStack createdMap) { + this.createdMap = createdMap.clone(); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickBlockEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickBlockEvent.java new file mode 100644 index 000000000..40c3348f2 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickBlockEvent.java @@ -0,0 +1,32 @@ +package io.papermc.paper.event.player; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Event that is fired when a player uses the pick item functionality on a block + * (middle-clicking a block to get the appropriate item). + * After the handling of this event, the contents of the source and the target slot will be swapped, + * and the currently selected hotbar slot of the player will be set to the target slot. + */ +@NullMarked +public class PlayerPickBlockEvent extends PlayerPickItemEvent { + private final Block block; + + @ApiStatus.Internal + public PlayerPickBlockEvent(final Player player, final Block block, final boolean includeData, final int targetSlot, final int sourceSlot) { + super(player, includeData, targetSlot, sourceSlot); + this.block = block; + } + + /** + * Retrieves the block associated with this event. + * + * @return the block involved in the event + */ + public Block getBlock() { + return this.block; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickEntityEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickEntityEvent.java new file mode 100644 index 000000000..a12b244cf --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickEntityEvent.java @@ -0,0 +1,32 @@ +package io.papermc.paper.event.player; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Event that is fired when a player uses the pick item functionality on an entity + * (middle-clicking an entity to get the appropriate item). + * After the handling of this event, the contents of the source and the target slot will be swapped, + * and the currently selected hotbar slot of the player will be set to the target slot. + */ +@NullMarked +public class PlayerPickEntityEvent extends PlayerPickItemEvent { + private final Entity entity; + + @ApiStatus.Internal + public PlayerPickEntityEvent(final Player player, final Entity entity, final boolean includeData, final int targetSlot, final int sourceSlot) { + super(player, includeData, targetSlot, sourceSlot); + this.entity = entity; + } + + /** + * Retrieves the entity associated with this event. + * + * @return the entity involved in the event + */ + public Entity getEntity() { + return this.entity; + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java index 7de240399..93c498d77 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java @@ -10,27 +10,44 @@ import org.jetbrains.annotations.Range; import org.jspecify.annotations.NullMarked; /** - * Event that is fired when a player uses the pick item functionality (middle-clicking a block or entity to get the - * appropriate item). After the handling of this event, the contents of the source and the target slot will be swapped + * Event that is fired when a player uses the pick item functionality + * (middle-clicking a {@link PlayerPickBlockEvent block} + * or {@link PlayerPickEntityEvent entity} to get the appropriate item). + * After the handling of this event, the contents of the source and the target slot will be swapped, * and the currently selected hotbar slot of the player will be set to the target slot. + * + * @see PlayerPickEntityEvent + * @see PlayerPickBlockEvent */ @NullMarked -public class PlayerPickItemEvent extends PlayerEvent implements Cancellable { +public abstract class PlayerPickItemEvent extends PlayerEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); + private final boolean includeData; + private int targetSlot; private int sourceSlot; private boolean cancelled; @ApiStatus.Internal - public PlayerPickItemEvent(final Player player, final int targetSlot, final int sourceSlot) { + protected PlayerPickItemEvent(final Player player, final boolean includeData, final int targetSlot, final int sourceSlot) { super(player); + this.includeData = includeData; this.targetSlot = targetSlot; this.sourceSlot = sourceSlot; } + /** + * Checks whether the player wants block/entity data included. + * + * @return {@code true} if data is included, otherwise {@code false}. + */ + public boolean isIncludeData() { + return includeData; + } + /** * Returns the slot the item that is being picked goes into. * diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/CatTypeRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/CatTypeRegistryEntry.java new file mode 100644 index 000000000..b818d61cd --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/CatTypeRegistryEntry.java @@ -0,0 +1,45 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import org.bukkit.entity.Cat; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link Cat.Type} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface CatTypeRegistryEntry { + + /** + * Provides the client texture asset of the cat type, which represents the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset clientTextureAsset(); + + /** + * A mutable builder for the {@link CatTypeRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #clientTextureAsset(ClientTextureAsset)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends CatTypeRegistryEntry, RegistryBuilder { + + /** + * Sets the client texture asset of the cat type, which is the location of the texture to use. + * + * @param clientTextureAsset the client texture asset. + * @return this builder instance. + * @see CatTypeRegistryEntry#clientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder clientTextureAsset(ClientTextureAsset clientTextureAsset); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/ChickenVariantRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/ChickenVariantRegistryEntry.java new file mode 100644 index 000000000..104c01ddc --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/ChickenVariantRegistryEntry.java @@ -0,0 +1,78 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import org.bukkit.entity.Chicken; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link Chicken.Variant} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface ChickenVariantRegistryEntry { + + /** + * The model of the chicken variant to render the configured texture on. + */ + enum Model { + /** + * The normal chicken model. + */ + NORMAL, + + /** + * The cold chicken model. + */ + COLD, + } + + /** + * Provides the client texture asset of the chicken variant, which represents the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset clientTextureAsset(); + + /** + * Provides the model of the chicken variant. + * + * @return the model. + */ + Model model(); + + /** + * A mutable builder for the {@link ChickenVariantRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #clientTextureAsset(ClientTextureAsset)}
  • + *
  • {@link #model(Model)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends ChickenVariantRegistryEntry, RegistryBuilder { + + /** + * Sets the client texture asset of the chicken variant, which is the location of the texture to use. + * + * @param clientTextureAsset the client texture asset. + * @return this builder instance. + * @see ChickenVariantRegistryEntry#clientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder clientTextureAsset(ClientTextureAsset clientTextureAsset); + + /** + * Sets the model to use for this chicken variant. + * + * @param model the model. + * @return this builder instance. + * @see ChickenVariantRegistryEntry#model() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder model(Model model); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/CowVariantRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/CowVariantRegistryEntry.java new file mode 100644 index 000000000..dce4a959d --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/CowVariantRegistryEntry.java @@ -0,0 +1,83 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import org.bukkit.entity.Cow; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link Cow.Variant} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface CowVariantRegistryEntry { + + /** + * The model of the cow variant to render the configured texture on. + */ + enum Model { + /** + * The normal cow model. + */ + NORMAL, + + /** + * The cold cow model. + */ + COLD, + + /** + * The warm cow model. + */ + WARM, + } + + /** + * Provides the client texture asset of the cow variant, which represents the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset clientTextureAsset(); + + /** + * Provides the model of the cow variant. + * + * @return the model. + */ + Model model(); + + /** + * A mutable builder for the {@link CowVariantRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #clientTextureAsset(ClientTextureAsset)}
  • + *
  • {@link #model(Model)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends CowVariantRegistryEntry, RegistryBuilder { + + /** + * Sets the client texture asset of the cow variant, which is the location of the texture to use. + * + * @param clientTextureAsset the client texture asset. + * @return this builder instance. + * @see CowVariantRegistryEntry#clientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder clientTextureAsset(ClientTextureAsset clientTextureAsset); + + /** + * Sets the model to use for this cow variant. + * + * @param model the model. + * @return this builder instance. + * @see CowVariantRegistryEntry#model() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder model(Model model); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/FrogVariantRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/FrogVariantRegistryEntry.java new file mode 100644 index 000000000..7f9c5e876 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/FrogVariantRegistryEntry.java @@ -0,0 +1,45 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import org.bukkit.entity.Frog; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link Frog.Variant} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface FrogVariantRegistryEntry { + + /** + * Provides the client texture asset of the frog variant, which represents the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset clientTextureAsset(); + + /** + * A mutable builder for the {@link FrogVariantRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #clientTextureAsset(ClientTextureAsset)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends FrogVariantRegistryEntry, RegistryBuilder { + + /** + * Sets the client texture asset of the frog variant, which is the location of the texture to use. + * + * @param clientTextureAsset the client texture asset. + * @return this builder instance. + * @see FrogVariantRegistryEntry#clientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder clientTextureAsset(ClientTextureAsset clientTextureAsset); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/PigVariantRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/PigVariantRegistryEntry.java new file mode 100644 index 000000000..02c043e83 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/PigVariantRegistryEntry.java @@ -0,0 +1,78 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import org.bukkit.entity.Pig; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link Pig.Variant} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface PigVariantRegistryEntry { + + /** + * The model of the pig variant to render the configured texture on. + */ + enum Model { + /** + * The normal pig model. + */ + NORMAL, + + /** + * The cold pig model. + */ + COLD, + } + + /** + * Provides the client texture asset of the pig variant, which represents the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset clientTextureAsset(); + + /** + * Provides the model of the pig variant. + * + * @return the model. + */ + Model model(); + + /** + * A mutable builder for the {@link PigVariantRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #clientTextureAsset(ClientTextureAsset)}
  • + *
  • {@link #model(Model)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends PigVariantRegistryEntry, RegistryBuilder { + + /** + * Sets the client texture asset of the pig variant, which is the location of the texture to use. + * + * @param clientTextureAsset the client texture asset. + * @return this builder instance. + * @see PigVariantRegistryEntry#clientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder clientTextureAsset(ClientTextureAsset clientTextureAsset); + + /** + * Sets the model to use for this pig variant. + * + * @param model the model. + * @return this builder instance. + * @see PigVariantRegistryEntry#model() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder model(Model model); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/WolfVariantRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/WolfVariantRegistryEntry.java new file mode 100644 index 000000000..786b8bd82 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/WolfVariantRegistryEntry.java @@ -0,0 +1,81 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import org.bukkit.entity.Wolf; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific registry entry for the {@link Wolf.Variant} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface WolfVariantRegistryEntry { + + /** + * Provides the client texture asset of the wolf variant for when it is angry, which is the location of the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset angryClientTextureAsset(); + + /** + * Provides the client texture asset of the wolf variant for when it is wild, which is the location of the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset wildClientTextureAsset(); + + /** + * Provides the client texture asset of the wolf variant for when it is tame, which is the location of the texture to use. + * + * @return the client texture asset. + */ + ClientTextureAsset tameClientTextureAsset(); + + /** + * A mutable builder for the {@link WolfVariantRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #angryClientTextureAsset(ClientTextureAsset)}
  • + *
  • {@link #wildClientTextureAsset(ClientTextureAsset)}
  • + *
  • {@link #tameClientTextureAsset(ClientTextureAsset)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends WolfVariantRegistryEntry, RegistryBuilder { + + /** + * Sets the client texture asset of the wolf variant for when it is angry, which is the location of the texture to use. + * + * @param angryClientTextureAsset the client texture asset. + * @return this builder instance. + * @see WolfVariantRegistryEntry#angryClientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder angryClientTextureAsset(ClientTextureAsset angryClientTextureAsset); + + /** + * Sets the client texture asset of the wolf variant for when it is wild, which is the location of the texture to use. + * + * @param wildClientTextureAsset the client texture asset. + * @return this builder instance. + * @see WolfVariantRegistryEntry#wildClientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder wildClientTextureAsset(ClientTextureAsset wildClientTextureAsset); + + /** + * Sets the client texture asset of the wolf variant for when it is tame, which is the location of the texture to use. + * + * @param tameClientTextureAsset the client texture asset. + * @return this builder instance. + * @see WolfVariantRegistryEntry#tameClientTextureAsset() + */ + @Contract(value = "_ -> this", mutates = "this") + Builder tameClientTextureAsset(ClientTextureAsset tameClientTextureAsset); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/client/ClientTextureAsset.java b/paper-api/src/main/java/io/papermc/paper/registry/data/client/ClientTextureAsset.java new file mode 100644 index 000000000..715f1759e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/client/ClientTextureAsset.java @@ -0,0 +1,66 @@ +package io.papermc.paper.registry.data.client; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; + +/** + * A data-centric version-specific representation of a client texture asset, composed of an identifier and a path. + * Follows the same, version-specific, compatibility guarantees as the RegistryEntry types it is used in. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface ClientTextureAsset { + + /** + * The identifier of the client texture asset, uniquely identifying the asset on the client. + * + * @return the identifier. + */ + Key identifier(); + + /** + * The path of the texture on the client, split into a namespace and a path/key. + * + * @return the texture path. + */ + Key texturePath(); + + /** + * Creates a new {@link ClientTextureAsset} with the specified identifier and texture path. + * + * @param identifier the unique identifier for the client texture asset. + * @param texturePath the path where the asset is located on the client. + * @return a new {@code ClientAsset} instance. + */ + @Contract("_,_ -> new") + static ClientTextureAsset clientTextureAsset(final Key identifier, final Key texturePath) { + return new ClientTextureAssetImpl(identifier, texturePath); + } + + /** + * Creates a new {@link ClientTextureAsset} using the provided identifier and infers the texture path from it. + * + * @param identifier the unique identifier for the client texture asset. + * @return a new {@code ClientAsset} instance. + */ + @Contract("_ -> new") + static ClientTextureAsset clientTextureAsset(final Key identifier) { + return new ClientTextureAssetImpl(identifier, ClientTextureAssetImpl.pathFromIdentifier(identifier)); + } + + /** + * Creates a new {@link ClientTextureAsset} from the provided string-formatted {@link Key} + * and infers the texture path from it. + *

+ * The identifier string must conform to the {@link KeyPattern} format. + * + * @param identifier the string representation of the asset's identifier. + * @return a new {@code ClientAsset} instance. + */ + @Contract("_ -> new") + static ClientTextureAsset clientTextureAsset(final @KeyPattern String identifier) { + return clientTextureAsset(Key.key(identifier)); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/client/ClientTextureAssetImpl.java b/paper-api/src/main/java/io/papermc/paper/registry/data/client/ClientTextureAssetImpl.java new file mode 100644 index 000000000..ad51a33a6 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/client/ClientTextureAssetImpl.java @@ -0,0 +1,31 @@ +package io.papermc.paper.registry.data.client; + +import net.kyori.adventure.key.Key; +import org.intellij.lang.annotations.Subst; +import org.jspecify.annotations.NullMarked; + +/** + * Package local implementation of the {@link ClientTextureAsset} type. + * Chosen over bridging into server internals as no internal types are required for this. + */ +@NullMarked +record ClientTextureAssetImpl( + Key identifier, + Key texturePath +) implements ClientTextureAsset { + + /** + * Constructs the default asset path from the identifier of the asset. + * Mirrors internal logic in net.minecraft.core.ClientAsset + * + * @param identifier the identifier of the asset. + * @return the key/path of the asset. + */ + static Key pathFromIdentifier(@Subst("") final Key identifier) { + return Key.key( + identifier.namespace(), + "textures/" + identifier.value() + ".png" + ); + } + +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java index 71b245606..0cf04f0e2 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java @@ -2,15 +2,27 @@ package io.papermc.paper.registry.event; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.data.BannerPatternRegistryEntry; +import io.papermc.paper.registry.data.CatTypeRegistryEntry; +import io.papermc.paper.registry.data.ChickenVariantRegistryEntry; +import io.papermc.paper.registry.data.CowVariantRegistryEntry; import io.papermc.paper.registry.data.DamageTypeRegistryEntry; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; +import io.papermc.paper.registry.data.FrogVariantRegistryEntry; import io.papermc.paper.registry.data.GameEventRegistryEntry; import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; +import io.papermc.paper.registry.data.PigVariantRegistryEntry; +import io.papermc.paper.registry.data.WolfVariantRegistryEntry; import org.bukkit.Art; import org.bukkit.GameEvent; import org.bukkit.block.banner.PatternType; import org.bukkit.damage.DamageType; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Cat; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Frog; +import org.bukkit.entity.Pig; +import org.bukkit.entity.Wolf; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -28,9 +40,15 @@ public final class RegistryEvents { // @GeneratedFrom 1.21.5 public static final RegistryEventProvider GAME_EVENT = create(RegistryKey.GAME_EVENT); public static final RegistryEventProvider DAMAGE_TYPE = create(RegistryKey.DAMAGE_TYPE); + public static final RegistryEventProvider WOLF_VARIANT = create(RegistryKey.WOLF_VARIANT); public static final RegistryEventProvider ENCHANTMENT = create(RegistryKey.ENCHANTMENT); public static final RegistryEventProvider BANNER_PATTERN = create(RegistryKey.BANNER_PATTERN); public static final RegistryEventProvider PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT); + public static final RegistryEventProvider CAT_VARIANT = create(RegistryKey.CAT_VARIANT); + public static final RegistryEventProvider FROG_VARIANT = create(RegistryKey.FROG_VARIANT); + public static final RegistryEventProvider CHICKEN_VARIANT = create(RegistryKey.CHICKEN_VARIANT); + public static final RegistryEventProvider COW_VARIANT = create(RegistryKey.COW_VARIANT); + public static final RegistryEventProvider PIG_VARIANT = create(RegistryKey.PIG_VARIANT); // End generate - RegistryEvents private RegistryEvents() { diff --git a/paper-api/src/main/java/io/papermc/paper/world/damagesource/CombatEntry.java b/paper-api/src/main/java/io/papermc/paper/world/damagesource/CombatEntry.java new file mode 100644 index 000000000..7b5256cff --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/world/damagesource/CombatEntry.java @@ -0,0 +1,82 @@ +package io.papermc.paper.world.damagesource; + +import io.papermc.paper.InternalAPIBridge; +import org.bukkit.damage.DamageSource; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * Represents a combat entry + */ +@NullMarked +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface CombatEntry { + + /** + * Gets the damage source. + * + * @return the damage source + */ + DamageSource getDamageSource(); + + /** + * Gets the amount of damage caused. + * + * @return the amount of damage caused + */ + float getDamage(); + + /** + * Gets the fall location type at the time of this damage. + * + * @return the fall location type + */ + @Nullable FallLocationType getFallLocationType(); + + /** + * Gets the fall distance at the time of this damage. + * + * @return the fall distance + */ + float getFallDistance(); + + /** + * Creates a new combat entry. + *

+ * The fall location and fall distance will be calculated from the entity's current state. + * + * @param entity entity + * @param damageSource damage source + * @param damage damage amount + * @return combat entry + * @see #combatEntry(DamageSource, float, FallLocationType, float) + */ + static CombatEntry combatEntry(final LivingEntity entity, final DamageSource damageSource, final float damage) { + return InternalAPIBridge.get().createCombatEntry(entity, damageSource, damage); + } + + /** + * Creates a new combat entry + * + * @param damageSource damage source + * @param damage damage amount + * @param fallLocationType fall location type + * @param fallDistance fall distance + * @return a new combat entry + * @see CombatTracker#calculateFallLocationType() + * @see Entity#getFallDistance() + */ + static CombatEntry combatEntry( + final DamageSource damageSource, + final float damage, + @Nullable final FallLocationType fallLocationType, + final float fallDistance + ) { + return InternalAPIBridge.get().createCombatEntry(damageSource, damage, fallLocationType, fallDistance); + } + +} diff --git a/paper-api/src/main/java/io/papermc/paper/world/damagesource/CombatTracker.java b/paper-api/src/main/java/io/papermc/paper/world/damagesource/CombatTracker.java new file mode 100644 index 000000000..22c6d9732 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/world/damagesource/CombatTracker.java @@ -0,0 +1,110 @@ +package io.papermc.paper.world.damagesource; + +import net.kyori.adventure.text.Component; +import org.bukkit.entity.LivingEntity; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import java.util.List; + +/** + * Represents entity's combat tracker + */ +@NullMarked +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface CombatTracker { + + /** + * Gets the entity behind this combat tracker. + * + * @return the entity behind this combat tracker + */ + LivingEntity getEntity(); + + /** + * Gets the list of recorded combat entries. + *

+ * The returned list is a copy, so any modifications + * to its contents won't affect this entity's + * combat history. + * + * @return the list of combat entries + * @see #setCombatEntries(List) + */ + List getCombatEntries(); + + /** + * Sets the entity's combat history. + *

+ * Note that overriding the entity's combat history won't + * affect the entity's current or new combat state. + * Reset the current combat state and register new combat entries instead + * if you want the new history to affect the combat state. + * + * @param combatEntries combat entries + * @see #resetCombatState() + * @see #addCombatEntry(CombatEntry) + */ + void setCombatEntries(List combatEntries); + + /** + * Calculates the most significant fall damage entry. + * + * @return the most significant fall damage entry + */ + @Nullable CombatEntry computeMostSignificantFall(); + + /** + * Checks whether the entity is in combat, + * i.e. has taken damage from an entity + * since the combat tracking has begun. + * + * @return whether the entity is in combat + */ + boolean isInCombat(); + + /** + * Checks whether the entity has started recording damage, + * i.e. its combat tracking is active. + * + * @return whether the entity has started recording damage + */ + boolean isTakingDamage(); + + /** + * Gets the last or current combat duration. + * + * @return the combat duration + * @see #isInCombat() + */ + int getCombatDuration(); + + /** + * Adds a new entry the pool of combat entries, + * updating the entity's combat state. + * + * @param combatEntry combat entry + */ + void addCombatEntry(CombatEntry combatEntry); + + /** + * Constructs a death message based on the current combat history. + * + * @return a death message + */ + Component getDeathMessage(); + + /** + * Resets entity's combat state, clearing combat history. + */ + void resetCombatState(); + + /** + * Calculates the fall location type from the current entity's location. + * + * @return the fall location type + */ + @Nullable FallLocationType calculateFallLocationType(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/world/damagesource/FallLocationType.java b/paper-api/src/main/java/io/papermc/paper/world/damagesource/FallLocationType.java new file mode 100644 index 000000000..1dcec3aef --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/world/damagesource/FallLocationType.java @@ -0,0 +1,63 @@ +package io.papermc.paper.world.damagesource; + +import net.kyori.adventure.translation.Translatable; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Represents a type of location from which the entity fell. + */ +@NullMarked +@ApiStatus.Experimental +public sealed interface FallLocationType extends Translatable permits FallLocationTypeImpl { + + /** + * Gets the fall location id. + * + * @return the fall location id + */ + String id(); + + /** + * Gets the translation key used for a fall death message + * caused by falling from this location + * + * @return the translation key + */ + @Override + String translationKey(); + + /** + * The entity was not within a special fall location. + */ + FallLocationType GENERIC = new FallLocationTypeImpl("generic"); + /** + * The entity was within the ladder. + */ + FallLocationType LADDER = new FallLocationTypeImpl("ladder"); + /** + * The entity was in vines. + */ + FallLocationType VINES = new FallLocationTypeImpl("vines"); + /** + * The entity was in weeping wines. + */ + FallLocationType WEEPING_VINES = new FallLocationTypeImpl("weeping_vines"); + /** + * The entity was in twisting vines. + */ + FallLocationType TWISTING_VINES = new FallLocationTypeImpl("twisting_vines"); + /** + * The entity was in scaffolding. + */ + FallLocationType SCAFFOLDING = new FallLocationTypeImpl("scaffolding"); + /** + * The entity was within some other climbable block. + */ + FallLocationType OTHER_CLIMBABLE = new FallLocationTypeImpl("other_climbable"); + /** + * The entity was in water. + */ + FallLocationType WATER = new FallLocationTypeImpl("water"); + +} diff --git a/paper-api/src/main/java/io/papermc/paper/world/damagesource/FallLocationTypeImpl.java b/paper-api/src/main/java/io/papermc/paper/world/damagesource/FallLocationTypeImpl.java new file mode 100644 index 000000000..c5b97cea3 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/world/damagesource/FallLocationTypeImpl.java @@ -0,0 +1,14 @@ +package io.papermc.paper.world.damagesource; + +import org.jspecify.annotations.NullMarked; + +@NullMarked +record FallLocationTypeImpl(String id) implements FallLocationType { + + @Override + public String translationKey() { + // Same as net.minecraft.world.damagesource.FallLocation#languageKey + return "death.fell.accident." + this.id; + } + +} diff --git a/paper-api/src/main/java/org/bukkit/Bukkit.java b/paper-api/src/main/java/org/bukkit/Bukkit.java index ee791bf62..c9ea6559f 100644 --- a/paper-api/src/main/java/org/bukkit/Bukkit.java +++ b/paper-api/src/main/java/org/bukkit/Bukkit.java @@ -14,6 +14,7 @@ import java.util.Set; import java.util.UUID; import java.util.function.Consumer; import java.util.logging.Logger; +import io.papermc.paper.configuration.ServerConfiguration; import net.kyori.adventure.text.Component; import org.bukkit.Warning.WarningState; import org.bukkit.advancement.Advancement; @@ -1435,6 +1436,15 @@ public final class Bukkit { return server.getOnlineMode(); } + /** + * Retrieves the server configuration. + * + * @return the instance of ServerConfiguration containing the server's configuration details + */ + public static @NotNull ServerConfiguration getServerConfig() { + return server.getServerConfig(); + } + /** * Gets whether this server allows flying or not. * diff --git a/paper-api/src/main/java/org/bukkit/Location.java b/paper-api/src/main/java/org/bukkit/Location.java index 20e30fa5a..a4a5444d0 100644 --- a/paper-api/src/main/java/org/bukkit/Location.java +++ b/paper-api/src/main/java/org/bukkit/Location.java @@ -732,7 +732,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Returns a copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ()) * @return A copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ()) - * @throws NullPointerException if {{@link #getWorld()}} is {@code null} + * @throws NullPointerException if {@link #getWorld()} is {@code null} */ @NotNull public Location toHighestLocation() { diff --git a/paper-api/src/main/java/org/bukkit/MusicInstrument.java b/paper-api/src/main/java/org/bukkit/MusicInstrument.java index 0b987a12e..096723765 100644 --- a/paper-api/src/main/java/org/bukkit/MusicInstrument.java +++ b/paper-api/src/main/java/org/bukkit/MusicInstrument.java @@ -5,10 +5,12 @@ import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; import java.util.Collection; import java.util.Collections; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import net.kyori.adventure.text.Component; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; -public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable { // Paper - translation keys +@NullMarked +public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable { // Start generate - MusicInstrument // @GeneratedFrom 1.21.5 @@ -38,7 +40,7 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran */ @Nullable @Deprecated(since = "1.20.1") - public static MusicInstrument getByKey(@NotNull NamespacedKey namespacedKey) { + public static MusicInstrument getByKey(final NamespacedKey namespacedKey) { return Registry.INSTRUMENT.get(namespacedKey); } @@ -48,25 +50,50 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran * @return the memoryKeys * @deprecated use {@link Registry#iterator()}. */ - @NotNull @Deprecated(since = "1.20.1") public static Collection values() { return Collections.unmodifiableCollection(Lists.newArrayList(Registry.INSTRUMENT)); } - @NotNull - private static MusicInstrument getInstrument(@NotNull String key) { + private static MusicInstrument getInstrument(final String key) { return RegistryAccess.registryAccess().getRegistry(RegistryKey.INSTRUMENT).getOrThrow(NamespacedKey.minecraft(key)); } - // Paper start - deprecate getKey + /** + * Gets the use duration of this music instrument. + * + * @return the duration expressed in seconds. + */ + public abstract float getDuration(); + + /** + * Gets the range of the sound. + * + * @return the range of the sound. + */ + public abstract float getRange(); + + /** + * Provides the description of this instrument as displayed to the client. + * + * @return the description component. + */ + public abstract Component description(); + + /** + * Gets the sound for this instrument. + * + * @return the sound + */ + public abstract Sound getSound(); + /** * @deprecated use {@link Registry#getKey(Keyed)}, {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)}, * and {@link io.papermc.paper.registry.RegistryKey#INSTRUMENT}. MusicInstruments can exist without a key. */ @Deprecated(forRemoval = true, since = "1.20.5") @Override - public abstract @NotNull NamespacedKey getKey(); + public abstract NamespacedKey getKey(); /** * @deprecated use {@link Registry#getKey(Keyed)}, {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)}, @@ -78,15 +105,11 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran return Keyed.super.key(); } - // Paper end - deprecate getKey - - // Paper start - mark translation key as deprecated /** * @deprecated this method assumes that the instrument description * always be a translatable component which is not guaranteed. */ @Override @Deprecated(forRemoval = true) - public abstract @NotNull String translationKey(); - // Paper end - mark translation key as deprecated + public abstract String translationKey(); } diff --git a/paper-api/src/main/java/org/bukkit/OfflinePlayer.java b/paper-api/src/main/java/org/bukkit/OfflinePlayer.java index c749a898e..6f83097b1 100644 --- a/paper-api/src/main/java/org/bukkit/OfflinePlayer.java +++ b/paper-api/src/main/java/org/bukkit/OfflinePlayer.java @@ -287,13 +287,28 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio // Paper end /** - * Gets the Location where the player will spawn at, null if they + * Gets the Location where the player will spawn at, {@code null} if they + * don't have a valid respawn point. + *
+ * Unlike online players, the location if found will not be loaded by default. + * + * @return respawn location if exists, otherwise {@code null}. + * @see #getRespawnLocation(boolean) for more fine-grained control over chunk loading and validation behaviour. + */ + default @Nullable Location getRespawnLocation() { + return this.getRespawnLocation(false); // keep old behavior for offline players + } + + /** + * Gets the Location where the player will spawn at, {@code null} if they * don't have a valid respawn point. * - * @return respawn location if exists, otherwise null. + * @param loadLocationAndValidate load the expected respawn location to retrieve the exact position of the spawn + * block and check if this position is still valid or not. Loading the location + * will induce a sync chunk load and must hence be used with caution. + * @return respawn location if exists, otherwise {@code null}. */ - @Nullable - public Location getRespawnLocation(); + @Nullable Location getRespawnLocation(boolean loadLocationAndValidate); /** * Increments the given statistic for this player. diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index 5f649c86c..ed899c4cb 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -14,6 +14,7 @@ import java.util.Set; import java.util.UUID; import java.util.function.Consumer; import java.util.logging.Logger; +import io.papermc.paper.configuration.ServerConfiguration; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; @@ -1267,6 +1268,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ public boolean getOnlineMode(); + /** + * Retrieves the server configuration. + * + * @return the instance of ServerConfiguration containing the server's configuration details + */ + @NotNull ServerConfiguration getServerConfig(); + /** * Gets whether this server allows flying or not. * @@ -2319,6 +2327,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @deprecated Server config options may be renamed or removed without notice. Prefer using existing API * wherever possible, rather than directly reading from a server config. * + * @see #getServerConfig() * @return The server's spigot config. */ @Deprecated(since = "1.21.4", forRemoval = true) @@ -2331,6 +2340,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @deprecated Server config options may be renamed or removed without notice. Prefer using existing API * wherever possible, rather than directly reading from a server config. * + * @see #getServerConfig() * @return The server's bukkit config. */ // Paper start @@ -2345,6 +2355,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @deprecated Server config options may be renamed or removed without notice. Prefer using existing API * wherever possible, rather than directly reading from a server config. * + * @see #getServerConfig() * @return The server's spigot config. */ @Deprecated(since = "1.21.4", forRemoval = true) @@ -2358,6 +2369,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @deprecated Server config options may be renamed or removed without notice. Prefer using existing API * wherever possible, rather than directly reading from a server config. * + * @see #getServerConfig() * @return The server's paper config. */ @Deprecated(since = "1.21.4", forRemoval = true) diff --git a/paper-api/src/main/java/org/bukkit/command/Command.java b/paper-api/src/main/java/org/bukkit/command/Command.java index 71eb845a4..27a7c69f2 100644 --- a/paper-api/src/main/java/org/bukkit/command/Command.java +++ b/paper-api/src/main/java/org/bukkit/command/Command.java @@ -7,7 +7,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.GameRule; import org.bukkit.Location; import org.bukkit.Server; diff --git a/paper-api/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/paper-api/src/main/java/org/bukkit/command/FormattedCommandAlias.java index abe256e1e..59fada9b1 100644 --- a/paper-api/src/main/java/org/bukkit/command/FormattedCommandAlias.java +++ b/paper-api/src/main/java/org/bukkit/command/FormattedCommandAlias.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.regex.Matcher; // Paper import java.util.regex.Pattern; // Paper +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; @@ -27,7 +29,7 @@ public class FormattedCommandAlias extends Command { if (throwable instanceof IllegalArgumentException) { sender.sendMessage(throwable.getMessage()); } else { - sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); + sender.sendMessage(Component.text("An internal error occurred while attempting to perform this command", NamedTextColor.RED)); } return false; } diff --git a/paper-api/src/main/java/org/bukkit/command/SimpleCommandMap.java b/paper-api/src/main/java/org/bukkit/command/SimpleCommandMap.java index 5df19bd70..4acda947b 100644 --- a/paper-api/src/main/java/org/bukkit/command/SimpleCommandMap.java +++ b/paper-api/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -5,7 +5,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -14,32 +13,26 @@ import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.command.defaults.BukkitCommand; import org.bukkit.command.defaults.HelpCommand; -import org.bukkit.command.defaults.PluginsCommand; import org.bukkit.command.defaults.ReloadCommand; -import org.bukkit.command.defaults.VersionCommand; import org.bukkit.entity.Player; import org.bukkit.util.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class SimpleCommandMap implements CommandMap { - protected final Map knownCommands; // Paper + protected final Map knownCommands; private final Server server; - // Paper start @org.jetbrains.annotations.ApiStatus.Internal public SimpleCommandMap(@NotNull final Server server, Map backing) { this.knownCommands = backing; - // Paper end this.server = server; setDefaultCommands(); } private void setDefaultCommands() { - register("bukkit", new VersionCommand("version")); register("bukkit", new ReloadCommand("reload")); - //register("bukkit", new PluginsCommand("plugins")); // Paper - register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper + register("bukkit", new co.aikar.timings.TimingsCommand("timings")); } public void setFallbackCommands() { diff --git a/paper-api/src/main/java/org/bukkit/command/defaults/HelpCommand.java b/paper-api/src/main/java/org/bukkit/command/defaults/HelpCommand.java index 9c63d9ded..a34bf3b98 100644 --- a/paper-api/src/main/java/org/bukkit/command/defaults/HelpCommand.java +++ b/paper-api/src/main/java/org/bukkit/command/defaults/HelpCommand.java @@ -10,8 +10,11 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.help.HelpMap; @@ -78,31 +81,29 @@ public class HelpCommand extends BukkitCommand { } if (topic == null || !topic.canSee(sender)) { - sender.sendMessage(ChatColor.RED + "No help for " + command); + sender.sendMessage(Component.text("No help for " + command, NamedTextColor.RED)); return true; } ChatPaginator.ChatPage page = ChatPaginator.paginate(topic.getFullText(sender), pageNumber, pageWidth, pageHeight); - StringBuilder header = new StringBuilder(); - header.append(ChatColor.YELLOW); - header.append("--------- "); - header.append(ChatColor.WHITE); - header.append("Help: "); - header.append(topic.getName()); - header.append(" "); + TextComponent.Builder header = Component.text() + .append(Component.text("--------- ", NamedTextColor.YELLOW)) + .append(Component.text("Help: ", NamedTextColor.WHITE)) + .append(Component.text(topic.getName())) + .append(Component.space()); if (page.getTotalPages() > 1) { - header.append("("); - header.append(page.getPageNumber()); - header.append("/"); - header.append(page.getTotalPages()); - header.append(") "); + header.append(Component.text("(")) + .append(Component.text(page.getPageNumber())) + .append(Component.text("/")) + .append(Component.text(page.getTotalPages())) + .append(Component.text(") ")); } - header.append(ChatColor.YELLOW); - for (int i = header.length(); i < ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH; i++) { - header.append("-"); - } - sender.sendMessage(header.toString()); + final TextComponent headerComponent = header.build(); + final int headerSize = PlainTextComponentSerializer.plainText().serialize(headerComponent).length(); + final int headerEndingCount = Math.max(0, ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH - headerSize); + + sender.sendMessage(headerComponent.append(Component.text("-".repeat(headerEndingCount), NamedTextColor.YELLOW))); sender.sendMessage(page.getLines()); diff --git a/paper-api/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/paper-api/src/main/java/org/bukkit/command/defaults/VersionCommand.java index 26bc02a53..29756f4ea 100644 --- a/paper-api/src/main/java/org/bukkit/command/defaults/VersionCommand.java +++ b/paper-api/src/main/java/org/bukkit/command/defaults/VersionCommand.java @@ -32,6 +32,7 @@ import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +@Deprecated(forRemoval = true) public class VersionCommand extends BukkitCommand { private VersionFetcher versionFetcher; // Paper - version command 2.0 private VersionFetcher getVersionFetcher() { // lazy load because unsafe isn't available at command registration diff --git a/paper-api/src/main/java/org/bukkit/entity/Armadillo.java b/paper-api/src/main/java/org/bukkit/entity/Armadillo.java index a8daf56dc..d4eacd26e 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Armadillo.java +++ b/paper-api/src/main/java/org/bukkit/entity/Armadillo.java @@ -1,8 +1,38 @@ package org.bukkit.entity; +import org.jspecify.annotations.NullMarked; + /** * Represents an Armadillo. */ +@NullMarked public interface Armadillo extends Animals { + /** + * Get the current state of the armadillo. + * + * @return the state of the armadillo + */ + State getState(); + + /** + * Attempt to roll up if the armadillo is {@link State#IDLE} + */ + void rollUp(); + + /** + * Attempt to roll out if the armadillo is not {@link State#IDLE} + */ + void rollOut(); + + /** + * Represents the current state of the armadillo. + */ + enum State { + IDLE, + ROLLING, + SCARED, + UNROLLING; + } + } diff --git a/paper-api/src/main/java/org/bukkit/entity/Entity.java b/paper-api/src/main/java/org/bukkit/entity/Entity.java index dc91a3cf3..66a31c5d8 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Entity.java +++ b/paper-api/src/main/java/org/bukkit/entity/Entity.java @@ -5,6 +5,7 @@ import java.util.Set; import java.util.UUID; import io.papermc.paper.datacomponent.DataComponentView; import io.papermc.paper.entity.LookAnchor; +import net.kyori.adventure.util.TriState; import org.bukkit.Chunk; // Paper import org.bukkit.EntityEffect; import org.bukkit.Location; @@ -19,6 +20,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.inventory.ItemStack; import org.bukkit.material.Directional; import org.bukkit.metadata.Metadatable; import org.bukkit.persistence.PersistentDataHolder; @@ -296,17 +298,43 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent /** * Sets if the entity has visual fire (it will always appear to be on fire). * + * @deprecated This method doesn't allow visually extinguishing a burning entity, + * use {@link #setVisualFire(TriState)} instead * @param fire whether visual fire is enabled */ + @Deprecated void setVisualFire(boolean fire); + /** + * Sets if the entity has visual fire (it will always appear to be on fire). + *

    + *
  • {@link TriState#NOT_SET} – will revert the entity's visual fire to default
  • + *
  • {@link TriState#TRUE} – will make the entity appear to be on fire
  • + *
  • {@link TriState#FALSE} – will make the entity appear to be not on fire
  • + *
+ * + * @param fire a TriState value representing the state of the visual fire. + */ + void setVisualFire(@NotNull TriState fire); + /** * Gets if the entity has visual fire (it will always appear to be on fire). * + * @deprecated This method can't properly reflect the three possible states of visual fire, + * use {@link #getVisualFire()} instead * @return whether visual fire is enabled */ + @Deprecated boolean isVisualFire(); + /** + * Retrieves the visual fire state of the object. + * + * @return A TriState indicating the current visual fire state. + */ + @NotNull + TriState getVisualFire(); + /** * Returns the entity's current freeze ticks (amount of ticks the entity has * been in powdered snow). @@ -511,6 +539,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent */ public boolean eject(); + /** + * Gets the {@link ItemStack} that a player would select / create (in creative mode) + * when using the pick block action on this entity. + * + * @return item stack result or an empty item stack + */ + @NotNull + ItemStack getPickItemStack(); + /** * Returns the distance this entity has fallen * diff --git a/paper-api/src/main/java/org/bukkit/entity/FishHook.java b/paper-api/src/main/java/org/bukkit/entity/FishHook.java index 1839195eb..fc280b419 100644 --- a/paper-api/src/main/java/org/bukkit/entity/FishHook.java +++ b/paper-api/src/main/java/org/bukkit/entity/FishHook.java @@ -1,6 +1,7 @@ package org.bukkit.entity; import org.bukkit.inventory.EquipmentSlot; +import io.papermc.paper.event.entity.FishHookStateChangeEvent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -306,6 +307,7 @@ public interface FishHook extends Projectile { /** * Represents a state in which a fishing hook may be. + * State transitions can be listened for using {@link FishHookStateChangeEvent} */ public enum HookState { diff --git a/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java b/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java index a4484ad3c..e8d7c3157 100644 --- a/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java @@ -485,9 +485,11 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * to validate if the current respawn location is still valid. * * @return respawn location if exists, otherwise null. + * @deprecated this method doesn't take the respawn angle into account, use + * {@link Player#getRespawnLocation(boolean)} with loadLocationAndValidate = false instead */ - @Nullable - Location getPotentialRespawnLocation(); + @Deprecated(since = "1.21.5") + @Nullable Location getPotentialRespawnLocation(); /** * @return the player's fishing hook if they are fishing diff --git a/paper-api/src/main/java/org/bukkit/entity/LivingEntity.java b/paper-api/src/main/java/org/bukkit/entity/LivingEntity.java index 61794d69b..7f2892dd9 100644 --- a/paper-api/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/paper-api/src/main/java/org/bukkit/entity/LivingEntity.java @@ -4,6 +4,8 @@ import java.util.Collection; import java.util.List; import java.util.Set; import java.util.UUID; +import io.papermc.paper.world.damagesource.CombatTracker; +import io.papermc.paper.world.damagesource.FallLocationType; import org.bukkit.FluidCollisionMode; import org.bukkit.Location; import org.bukkit.Material; @@ -21,6 +23,7 @@ import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -1452,4 +1455,12 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource */ boolean canUseEquipmentSlot(org.bukkit.inventory.@NotNull EquipmentSlot slot); // Paper end - Expose canUseSlot + + /** + * Gets the entity's combat tracker + * + * @return the entity's combat tracker + */ + @ApiStatus.Experimental + @NotNull CombatTracker getCombatTracker(); } diff --git a/paper-api/src/main/java/org/bukkit/entity/Player.java b/paper-api/src/main/java/org/bukkit/entity/Player.java index 9ccb7e901..d34419693 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Player.java +++ b/paper-api/src/main/java/org/bukkit/entity/Player.java @@ -12,6 +12,7 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; import io.papermc.paper.entity.LookAnchor; import io.papermc.paper.entity.PlayerGiveResult; +import io.papermc.paper.math.Position; import org.bukkit.BanEntry; import org.bukkit.DyeColor; import org.bukkit.Effect; @@ -52,7 +53,6 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.messaging.PluginMessageRecipient; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.bukkit.profile.PlayerProfile; import org.bukkit.scoreboard.Scoreboard; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -293,7 +293,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * set in the client, the {@link CompletableFuture} will complete with a * null value. */ - CompletableFuture retrieveCookie(NamespacedKey key); + CompletableFuture retrieveCookie(NamespacedKey key); /** * Stores a cookie in this player's client. @@ -545,6 +545,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public boolean isSleepingIgnored(); + /** + * Gets the Location where the player will spawn at, {@code null} if they + * don't have a valid respawn point. + *
+ * Unlike offline players, the location if found will be loaded to validate by default. + * + * @return respawn location if exists, otherwise {@code null}. + * @see #getRespawnLocation(boolean) for more fine-grained control over chunk loading and validation behaviour. + */ + @Override + default @Nullable Location getRespawnLocation() { + return this.getRespawnLocation(true); + } + /** * Sets the Location where the player will spawn at their bed. * @@ -1164,7 +1178,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated // Paper - public void sendSignChange(Location loc, @Nullable String[] lines) throws IllegalArgumentException; + public void sendSignChange(Location loc, @Nullable String @Nullable [] lines) throws IllegalArgumentException; /** * Send a sign change. This fakes a sign change packet for a user at @@ -1190,7 +1204,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated // Paper - public void sendSignChange(Location loc, @Nullable String[] lines, DyeColor dyeColor) throws IllegalArgumentException; + public void sendSignChange(Location loc, @Nullable String @Nullable [] lines, DyeColor dyeColor) throws IllegalArgumentException; /** * Send a sign change. This fakes a sign change packet for a user at @@ -1217,7 +1231,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated // Paper - public void sendSignChange(Location loc, @Nullable String[] lines, DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; + public void sendSignChange(Location loc, @Nullable String @Nullable [] lines, DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; /** * Send a TileState change. This fakes a TileState change for a user at @@ -2822,7 +2836,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. */ - public void addResourcePack(UUID id, String url, @Nullable byte[] hash, @Nullable String prompt, boolean force); + public void addResourcePack(UUID id, String url, byte @Nullable [] hash, @Nullable String prompt, boolean force); /** * Request that the player's client remove a resource pack sent by the @@ -3435,6 +3449,21 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ public void openSign(Sign sign, Side side); + /** + * Open a sign for editing by the player. + *

+ * The sign must only be placed locally for the player, which can be done with {@link #sendBlockChange(Location, BlockData)} and {@link #sendBlockUpdate(Location, TileState)}. + * A side-effect of this is that normal events, like {@link org.bukkit.event.block.SignChangeEvent} will not be called (unless there is an actual sign in the world). + * Additionally, the client may enforce distance limits to the opened position. + *

+ * + * @param block The block where the client has a sign placed + * @param side The side to edit + * @see io.papermc.paper.event.packet.UncheckedSignChangeEvent + */ + @ApiStatus.Experimental + void openVirtualSign(Position block, Side side); + /** * Shows the demo screen to the player, this screen is normally only seen in * the demo version of the game. diff --git a/paper-api/src/main/java/org/bukkit/entity/Wolf.java b/paper-api/src/main/java/org/bukkit/entity/Wolf.java index a1c7b6ba6..a6414ffc4 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Wolf.java +++ b/paper-api/src/main/java/org/bukkit/entity/Wolf.java @@ -5,7 +5,6 @@ import io.papermc.paper.registry.RegistryKey; import org.bukkit.DyeColor; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.jetbrains.annotations.NotNull; /** diff --git a/paper-api/src/main/java/org/bukkit/entity/Zombie.java b/paper-api/src/main/java/org/bukkit/entity/Zombie.java index 002fd6c7c..8d11ce904 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Zombie.java +++ b/paper-api/src/main/java/org/bukkit/entity/Zombie.java @@ -71,7 +71,7 @@ public interface Zombie extends Monster, Ageable { /** * Gets the amount of ticks until this entity will be converted to a Drowned * as a result of being underwater. - * + *
* When this reaches 0, the entity will be converted. * * @return conversion time @@ -82,7 +82,7 @@ public interface Zombie extends Monster, Ageable { /** * Sets the amount of ticks until this entity will be converted to a Drowned * as a result of being underwater. - * + *
* When this reaches 0, the entity will be converted. A value of less than 0 * will stop the current conversion process without converting the current * entity. @@ -121,7 +121,6 @@ public interface Zombie extends Monster, Ageable { * Make zombie start drowning * * @param drownedConversionTime Amount of time until zombie converts from drowning - * * @deprecated See {@link #setConversionTime(int)} */ @Deprecated @@ -136,7 +135,7 @@ public interface Zombie extends Monster, Ageable { * Set if zombie has its arms raised * * @param raised True to raise arms - * @deprecated use {{@link #setAggressive(boolean)}} + * @deprecated use {@link #setAggressive(boolean)} */ @Deprecated void setArmsRaised(boolean raised); diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityTransformEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityTransformEvent.java index e2450a660..6557aa19e 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityTransformEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityTransformEvent.java @@ -6,11 +6,12 @@ import org.bukkit.entity.Entity; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked; /** * Called when an entity is about to be replaced by another entity. */ +@NullMarked public class EntityTransformEvent extends EntityEvent implements Cancellable { private static final HandlerList HANDLER_LIST = new HandlerList(); @@ -22,10 +23,10 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable { private boolean cancelled; @ApiStatus.Internal - public EntityTransformEvent(@NotNull Entity original, @NotNull List convertedList, @NotNull TransformReason transformReason) { + public EntityTransformEvent(Entity original, List convertedList, TransformReason transformReason) { super(original); this.convertedList = Collections.unmodifiableList(convertedList); - this.converted = convertedList.get(0); + this.converted = convertedList.getFirst(); this.transformReason = transformReason; } @@ -34,7 +35,6 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable { * * @return The transformed entities. */ - @NotNull public List getTransformedEntities() { return this.convertedList; } @@ -47,7 +47,6 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable { * @return The transformed entity. * @see #getTransformedEntities() */ - @NotNull public Entity getTransformedEntity() { return this.converted; } @@ -57,7 +56,6 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable { * * @return The reason for conversion that has occurred. */ - @NotNull public TransformReason getTransformReason() { return this.transformReason; } @@ -72,13 +70,11 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable { this.cancelled = cancel; } - @NotNull @Override public HandlerList getHandlers() { return HANDLER_LIST; } - @NotNull public static HandlerList getHandlerList() { return HANDLER_LIST; } diff --git a/paper-api/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java index 85ecbfd6f..41b953a1c 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java @@ -18,27 +18,27 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca private static final HandlerList HANDLER_LIST = new HandlerList(); - private final AreaEffectCloud entity; + private final AreaEffectCloud effectCloud; private boolean allowEmptyAreaEffectCreation; private boolean cancelled; @ApiStatus.Internal @Deprecated(since = "1.20.2", forRemoval = true) - public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud entity) { - this(potion, null, null, null, entity); + public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud effectCloud) { + this(potion, null, null, null, effectCloud); } @ApiStatus.Internal - public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final AreaEffectCloud entity) { + public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final AreaEffectCloud effectCloud) { super(potion, hitEntity, hitBlock, hitFace); - this.entity = entity; + this.effectCloud = effectCloud; } @NotNull @Override public ThrownPotion getEntity() { - return (ThrownPotion) super.getEntity(); + return (ThrownPotion) this.entity; } /** @@ -48,10 +48,9 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca */ @NotNull public AreaEffectCloud getAreaEffectCloud() { - return entity; + return effectCloud; } - // Paper start /** * Sets if an Empty AreaEffectCloud may be created * @@ -69,7 +68,6 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca public boolean allowsEmptyCreation() { return allowEmptyAreaEffectCreation; } - // Paper end @Override public boolean isCancelled() { diff --git a/paper-api/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java index d49dffbc2..6316a2f1d 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java @@ -19,7 +19,9 @@ public class PlayerDeathEvent extends EntityDeathEvent { private int newExp = 0; private int newLevel = 0; private int newTotalExp = 0; + private boolean showDeathMessages; private Component deathMessage; + private Component deathScreenMessageOverride = null; private boolean doExpDrop; private boolean keepLevel = false; private boolean keepInventory = false; @@ -27,27 +29,28 @@ public class PlayerDeathEvent extends EntityDeathEvent { private final List itemsToKeep = new ArrayList<>(); @ApiStatus.Internal - public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final @Nullable Component deathMessage) { - this(player, damageSource, drops, droppedExp, 0, deathMessage); + public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final @Nullable Component deathMessage, final boolean showDeathMessages) { + this(player, damageSource, drops, droppedExp, 0, deathMessage, showDeathMessages); } @ApiStatus.Internal - public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final int newExp, final @Nullable Component deathMessage) { - this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage); + public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final int newExp, final @Nullable Component deathMessage, final boolean showDeathMessages) { + this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage, showDeathMessages); } @ApiStatus.Internal - public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage) { - this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true); + public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage, final boolean showDeathMessages) { + this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, showDeathMessages, true); } @ApiStatus.Internal - public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage, final boolean doExpDrop) { + public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage, final boolean showDeathMessages, final boolean doExpDrop) { super(player, damageSource, drops, droppedExp); this.newExp = newExp; this.newTotalExp = newTotalExp; this.newLevel = newLevel; this.deathMessage = deathMessage; + this.showDeathMessages = showDeathMessages; this.doExpDrop = doExpDrop; } @@ -76,6 +79,7 @@ public class PlayerDeathEvent extends EntityDeathEvent { this.newExp = newExp; this.newTotalExp = newTotalExp; this.newLevel = newLevel; + this.showDeathMessages = true; this.deathMessage = LegacyComponentSerializer.legacySection().deserializeOrNull(deathMessage); this.doExpDrop = doExpDrop; } @@ -86,6 +90,30 @@ public class PlayerDeathEvent extends EntityDeathEvent { return (Player) this.entity; } + /** + * Get whether the death message should be shown. + * By default, this is determined by {@link org.bukkit.GameRule#SHOW_DEATH_MESSAGES}. + * + * @return whether the death message should be shown + * @see #deathMessage() + * @see #deathScreenMessageOverride() + */ + public boolean getShowDeathMessages() { + return showDeathMessages; + } + + /** + * Set whether the death message should be shown. + * By default, this is determined by {@link org.bukkit.GameRule#SHOW_DEATH_MESSAGES}. + * + * @param displayDeathMessage whether the death message should be shown + * @see #deathMessage() + * @see #deathScreenMessageOverride() + */ + public void setShowDeathMessages(boolean displayDeathMessage) { + this.showDeathMessages = displayDeathMessage; + } + /** * Clarity method for getting the player. Not really needed except * for reasons of clarity. @@ -177,7 +205,7 @@ public class PlayerDeathEvent extends EntityDeathEvent { /** * Set the death message that will appear to everyone on the server. * - * @param deathMessage Message to appear to other players on the server. + * @param deathMessage message to appear to other players on the server. * @deprecated in favour of {@link #deathMessage(Component)} */ @Deprecated @@ -197,6 +225,32 @@ public class PlayerDeathEvent extends EntityDeathEvent { return LegacyComponentSerializer.legacySection().serializeOrNull(this.deathMessage); } + /** + * Overrides the death message that will appear on the death screen of the dying player. + * By default, this is null. + *

+ * If set to null, death screen message will be same as {@code deathMessage()}. + *

+ * If the message exceeds 256 characters it will be truncated. + * + * @param deathScreenMessageOverride Message to appear on the death screen to the dying player. + */ + public void deathScreenMessageOverride(@Nullable Component deathScreenMessageOverride) { + this.deathScreenMessageOverride = deathScreenMessageOverride; + } + + /** + * Get the death message override that will appear on the death screen of the dying player. + * By default, this is null. + *

+ * If set to null, death screen message will be same as {@code deathMessage()}. + *

+ * @return Message to appear on the death screen to the dying player. + */ + public @Nullable Component deathScreenMessageOverride() { + return this.deathScreenMessageOverride; + } + /** * @return should experience be dropped from this death */ diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerFishEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerFishEvent.java index 691037dec..d13c354d7 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerFishEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerFishEvent.java @@ -1,5 +1,6 @@ package org.bukkit.event.player; +import io.papermc.paper.event.entity.FishHookStateChangeEvent; import org.bukkit.entity.Entity; import org.bukkit.entity.FishHook; import org.bukkit.entity.Player; @@ -12,6 +13,8 @@ import org.jetbrains.annotations.Nullable; /** * Thrown when a player is fishing + * + *

If you want to monitor a fishhooks state transition, you can use {@link FishHookStateChangeEvent}.

*/ public class PlayerFishEvent extends PlayerEvent implements Cancellable { diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java index 757d8d699..aecee1357 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java @@ -1,6 +1,7 @@ package org.bukkit.event.player; import com.google.common.base.Preconditions; +import io.papermc.paper.event.player.AbstractRespawnEvent; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; @@ -15,17 +16,10 @@ import java.util.Set; * If changing player state, see {@link com.destroystokyo.paper.event.player.PlayerPostRespawnEvent} * because the player is "reset" between this event and that event and some changes won't persist. */ -public class PlayerRespawnEvent extends PlayerEvent { +public class PlayerRespawnEvent extends AbstractRespawnEvent { private static final HandlerList HANDLER_LIST = new HandlerList(); - private final boolean isBedSpawn; - private final boolean isAnchorSpawn; - private final boolean missingRespawnBlock; - private final RespawnReason respawnReason; - private final Set respawnFlags; - private Location respawnLocation; - @ApiStatus.Internal @Deprecated(since = "1.16.1", forRemoval = true) public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn) { @@ -35,40 +29,16 @@ public class PlayerRespawnEvent extends PlayerEvent { @ApiStatus.Internal @Deprecated(since = "1.19.4", forRemoval = true) public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn) { - this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, RespawnReason.PLUGIN); + this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, false, RespawnReason.PLUGIN); } @ApiStatus.Internal - @Deprecated(forRemoval = true) - public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, @NotNull final RespawnReason respawnReason) { - this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, false, respawnReason, com.google.common.collect.ImmutableSet.builder()); - } - - @ApiStatus.Internal - public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, final boolean missingRespawnBlock, @NotNull final RespawnReason respawnReason, @NotNull final com.google.common.collect.ImmutableSet.Builder respawnFlags) { - super(respawnPlayer); - this.respawnLocation = respawnLocation; - this.isBedSpawn = isBedSpawn; - this.isAnchorSpawn = isAnchorSpawn; - this.respawnReason = respawnReason; - this.missingRespawnBlock = missingRespawnBlock; - if (this.isBedSpawn) { respawnFlags.add(RespawnFlag.BED_SPAWN); } - if (this.isAnchorSpawn) { respawnFlags.add(RespawnFlag.ANCHOR_SPAWN); } - this.respawnFlags = respawnFlags.build(); + public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, final boolean missingRespawnBlock, @NotNull final RespawnReason respawnReason) { + super(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, missingRespawnBlock, respawnReason); } /** - * Gets the current respawn location - * - * @return Location current respawn location - */ - @NotNull - public Location getRespawnLocation() { - return this.respawnLocation; - } - - /** - * Sets the new respawn location + * Sets the new respawn location. * * @param respawnLocation new location for the respawn */ @@ -79,57 +49,6 @@ public class PlayerRespawnEvent extends PlayerEvent { this.respawnLocation = respawnLocation.clone(); } - /** - * Gets whether the respawn location is the player's bed. - * - * @return {@code true} if the respawn location is the player's bed. - */ - public boolean isBedSpawn() { - return this.isBedSpawn; - } - - /** - * Gets whether the respawn location is the player's respawn anchor. - * - * @return {@code true} if the respawn location is the player's respawn anchor. - */ - public boolean isAnchorSpawn() { - return this.isAnchorSpawn; - } - - /** - * Gets whether the player is missing a valid respawn block. - *

- * This will occur if the players respawn block is obstructed, - * or it is the first death after it was either destroyed or - * in case of a respawn anchor, ran out of charges. - * - * @return whether the player is missing a valid respawn block - */ - public boolean isMissingRespawnBlock() { - return this.missingRespawnBlock; - } - - /** - * Gets the reason this respawn event was called. - * - * @return the reason the event was called. - */ - @NotNull - public RespawnReason getRespawnReason() { - return this.respawnReason; - } - - /** - * Get the set of flags that apply to this respawn. - * - * @return an immutable set of the flags that apply to this respawn - */ - @NotNull - public @Unmodifiable Set getRespawnFlags() { - return this.respawnFlags; - } - @NotNull @Override public HandlerList getHandlers() { diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java index 07e98ba82..236f09c71 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java @@ -1,5 +1,6 @@ package org.bukkit.event.player; +import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect; import io.papermc.paper.entity.TeleportFlag; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -121,10 +122,9 @@ public class PlayerTeleportEvent extends PlayerMoveEvent { */ END_GATEWAY, /** - * Indicates the teleportation was caused by a player consuming chorus - * fruit + * Indicates the teleportation was caused by a player consuming an item with a {@link ConsumeEffect.TeleportRandomly} effect */ - CHORUS_FRUIT, + CONSUMABLE_EFFECT, /** * Indicates the teleportation was caused by a player exiting a vehicle */ @@ -137,6 +137,14 @@ public class PlayerTeleportEvent extends PlayerMoveEvent { * Indicates the teleportation was caused by an event not covered by * this enum */ - UNKNOWN + UNKNOWN; + + /** + * Indicates the teleportation was caused by a player consuming chorus + * fruit + * @deprecated in favor of {@link #CONSUMABLE_EFFECT} + */ + @Deprecated(since = "1.21.5", forRemoval = true) + public static final TeleportCause CHORUS_FRUIT = CONSUMABLE_EFFECT; } } diff --git a/paper-api/src/main/java/org/bukkit/event/server/TabCompleteEvent.java b/paper-api/src/main/java/org/bukkit/event/server/TabCompleteEvent.java index a136f6974..1262ad2d8 100644 --- a/paper-api/src/main/java/org/bukkit/event/server/TabCompleteEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/server/TabCompleteEvent.java @@ -87,7 +87,7 @@ public class TabCompleteEvent extends Event implements Cancellable { /** * Set the completions offered, overriding any already set. *
- * The passed collection will be cloned to a new List. You must call {{@link #getCompletions()}} to mutate from here + * The passed collection will be cloned to a new List. You must call {@link #getCompletions()} to mutate from here * * @param completions the new completions */ diff --git a/paper-api/src/main/java/org/bukkit/inventory/InventoryView.java b/paper-api/src/main/java/org/bukkit/inventory/InventoryView.java index 46f5f5017..5c5906421 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/InventoryView.java +++ b/paper-api/src/main/java/org/bukkit/inventory/InventoryView.java @@ -2,6 +2,7 @@ package org.bukkit.inventory; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryType; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -321,4 +322,16 @@ public interface InventoryView { */ @Deprecated(since = "1.21.1") // Paper public void setTitle(@NotNull String title); + + /** + * Gets the menu type of the inventory view if applicable. + *

+ * Some inventory types do not support a menu type. In such cases, this method + * returns null. This typically applies to inventories belonging to entities + * like players or animals (e.g., a horse). + * + * @return the menu type of the inventory view or null if not applicable + */ + @ApiStatus.Experimental + @Nullable MenuType getMenuType(); } diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemFactory.java b/paper-api/src/main/java/org/bukkit/inventory/ItemFactory.java index c1ee9659f..a01924439 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -210,12 +210,12 @@ public interface ItemFactory { @Deprecated(since = "1.19.3") // Paper ItemStack enchantItem(@NotNull final ItemStack item, final int level, final boolean allowTreasures); - // Paper start - Adventure /** * Creates a hover event for the given item. * * @param item The item * @return A hover event + * @throws IllegalArgumentException if the {@link ItemStack#getAmount()} is not between 1 and 99 */ @NotNull net.kyori.adventure.text.event.HoverEvent asHoverEvent(final @NotNull ItemStack item, final @NotNull java.util.function.UnaryOperator op); @@ -223,12 +223,13 @@ public interface ItemFactory { /** * Get the formatted display name of the {@link ItemStack}. * + * @apiNote this component include a {@link net.kyori.adventure.text.event.HoverEvent item hover event}. + * When used in chat, make sure to follow the ItemStack rules regarding amount, type, and other properties. * @param itemStack the {@link ItemStack} * @return display name of the {@link ItemStack} */ @NotNull net.kyori.adventure.text.Component displayName(@NotNull ItemStack itemStack); - // Paper end - Adventure // Paper start - add getI18NDisplayName /** diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java index 3179607e8..8a5a58408 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.HoverEvent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -706,6 +707,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat return Bukkit.getItemFactory().enchantWithLevels(this, levels, keySet, random); } + /** + * {@inheritDoc} + * + * @param op transformation on value + * @return a hover event + * @throws IllegalArgumentException if the {@link ItemStack#getAmount()} is not between 1 and 99 + */ @NotNull @Override public net.kyori.adventure.text.event.HoverEvent asHoverEvent(final @NotNull java.util.function.UnaryOperator op) { @@ -715,6 +723,8 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat /** * Get the formatted display name of the {@link ItemStack}. * + * @apiNote this component include a {@link net.kyori.adventure.text.event.HoverEvent item hover event}. + * When used in chat, make sure to follow the ItemStack rules regarding amount, type, and other properties. * @return display name of the {@link ItemStack} */ public net.kyori.adventure.text.@NotNull Component displayName() { diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/paper-api/src/main/java/org/bukkit/inventory/meta/ItemMeta.java index 1f7d294a7..82b8bd29c 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/ItemMeta.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -5,6 +5,9 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; +import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.item.ItemAdventurePredicate; import net.kyori.adventure.text.Component; import org.bukkit.NamespacedKey; import org.bukkit.Tag; @@ -1086,12 +1089,12 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste @NotNull ItemMeta clone(); - // Paper start - Add an API for can-place-on/can-break adventure mode predicates /** * Gets set of materials what given item can destroy in {@link org.bukkit.GameMode#ADVENTURE} * * @return Set of materials - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_BREAK} instead of this. */ @Deprecated(forRemoval = true, since = "1.14") Set getCanDestroy(); @@ -1100,7 +1103,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Sets set of materials what given item can destroy in {@link org.bukkit.GameMode#ADVENTURE} * * @param canDestroy Set of materials - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_BREAK} instead of this. */ @Deprecated(forRemoval = true, since = "1.14") void setCanDestroy(Set canDestroy); @@ -1109,7 +1113,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Gets set of materials where given item can be placed on in {@link org.bukkit.GameMode#ADVENTURE} * * @return Set of materials - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this. */ @Deprecated(forRemoval = true, since = "1.14") Set getCanPlaceOn(); @@ -1118,7 +1123,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Sets set of materials where given item can be placed on in {@link org.bukkit.GameMode#ADVENTURE} * * @param canPlaceOn Set of materials - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this. */ @Deprecated(forRemoval = true, since = "1.14") void setCanPlaceOn(Set canPlaceOn); @@ -1127,7 +1133,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Gets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE} * * @return Set of {@link com.destroystokyo.paper.Namespaced} - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_BREAK} instead of this. */ @Deprecated(forRemoval = true, since = "1.20.6") @NotNull @@ -1137,7 +1144,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Sets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE} * * @param canDestroy Collection of {@link com.destroystokyo.paper.Namespaced} - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_BREAK} instead of this. */ @Deprecated(forRemoval = true, since = "1.20.6") void setDestroyableKeys(@NotNull Collection canDestroy); @@ -1146,7 +1154,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Gets the collection of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE} * * @return Set of {@link com.destroystokyo.paper.Namespaced} - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this. */ @NotNull @Deprecated(forRemoval = true, since = "1.20.6") @@ -1156,7 +1165,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Sets the set of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE} * * @param canPlaceOn Collection of {@link com.destroystokyo.paper.Namespaced} - * @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates. + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this. */ @Deprecated(forRemoval = true, since = "1.20.6") void setPlaceableKeys(@NotNull Collection canPlaceOn); @@ -1165,7 +1175,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Checks for the existence of any keys that the item can be placed on * * @return true if this item has placeable keys - * @deprecated this API is unsupported and will be replaced + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#hasData(DataComponentType)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this. */ @Deprecated(forRemoval = true, since = "1.20.6") boolean hasPlaceableKeys(); @@ -1174,9 +1185,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste * Checks for the existence of any keys that the item can destroy * * @return true if this item has destroyable keys - * @deprecated this API is unsupported and will be replaced + * @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API. + * Please use {@link ItemStack#hasData(DataComponentType)} with {@link DataComponentTypes#CAN_BREAK} instead of this. */ @Deprecated(forRemoval = true, since = "1.20.6") boolean hasDestroyableKeys(); - // Paper end - Add an API for can-place-on/can-break adventure mode predicates } diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java b/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java index 02b0a3878..3364254ad 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java @@ -8,6 +8,7 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Unmodifiable; /** * Represents a potion or item that can have custom effects. @@ -74,6 +75,16 @@ public interface PotionMeta extends ItemMeta { @NotNull List getCustomEffects(); + /** + * All effects that this potion meta holds. + *

+ * This is a combination of the base potion type and any custom effects. + * + * @return an unmodifiable list of all effects. + */ + @NotNull + @Unmodifiable List getAllEffects(); + /** * Adds a custom potion effect to this potion. * @@ -146,6 +157,16 @@ public interface PotionMeta extends ItemMeta { */ void setColor(@Nullable Color color); + /** + * Computes the effective colour of this potion meta. + *

+ * This blends all custom effects, or uses a default fallback color. + * + * @return the effective potion color + */ + @NotNull + Color computeEffectiveColor(); + /** * Checks for existence of a custom potion name translation suffix. * diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java index 7e4f7cb2a..37827b19e 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -206,7 +206,16 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm if (result == null) { String path = name.replace('.', '/').concat(".class"); - JarEntry entry = jar.getJarEntry(path); + // Add details to zip file errors - help debug classloading + JarEntry entry; + try { + entry = jar.getJarEntry(path); + } catch (IllegalStateException zipFileClosed) { + if (plugin == null) { + throw zipFileClosed; + } + throw new IllegalStateException("The plugin classloader for " + plugin.getName() + " has thrown a zip file error.", zipFileClosed); + } if (entry != null) { byte[] classBytes; diff --git a/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java b/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java index c12cdc0b1..38f8c83e8 100644 --- a/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java +++ b/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java @@ -4,8 +4,12 @@ import io.papermc.generator.utils.ClassHelper; import io.papermc.paper.datacomponent.DataComponentType; import io.papermc.paper.datacomponent.DataComponentTypes; import io.papermc.paper.registry.data.BannerPatternRegistryEntry; +import io.papermc.paper.registry.data.CatTypeRegistryEntry; +import io.papermc.paper.registry.data.ChickenVariantRegistryEntry; +import io.papermc.paper.registry.data.CowVariantRegistryEntry; import io.papermc.paper.registry.data.DamageTypeRegistryEntry; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; +import io.papermc.paper.registry.data.FrogVariantRegistryEntry; import io.papermc.paper.registry.data.GameEventRegistryEntry; import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; import java.lang.reflect.Field; @@ -20,6 +24,8 @@ import java.util.Objects; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; +import io.papermc.paper.registry.data.PigVariantRegistryEntry; +import io.papermc.paper.registry.data.WolfVariantRegistryEntry; import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponents; import net.minecraft.core.particles.ParticleTypes; @@ -161,18 +167,18 @@ public final class RegistryEntries { entry(Registries.TRIM_MATERIAL, TrimMaterials.class, TrimMaterial.class).allowDirect().delayed(), entry(Registries.TRIM_PATTERN, TrimPatterns.class, TrimPattern.class).allowDirect().delayed(), entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).apiRegistryBuilder(DamageTypeRegistryEntry.Builder.class, "PaperDamageTypeRegistryEntry.PaperBuilder").delayed(), - entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).delayed(), + entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).apiRegistryBuilder(WolfVariantRegistryEntry.Builder.class, "PaperWolfVariantRegistryEntry.PaperBuilder").delayed(), entry(Registries.WOLF_SOUND_VARIANT, WolfSoundVariants.class, Wolf.SoundVariant.class), entry(Registries.ENCHANTMENT, Enchantments.class, Enchantment.class).apiRegistryBuilder(EnchantmentRegistryEntry.Builder.class, "PaperEnchantmentRegistryEntry.PaperBuilder").serializationUpdater("ENCHANTMENT_RENAME").delayed(), entry(Registries.JUKEBOX_SONG, JukeboxSongs.class, JukeboxSong.class).delayed(), entry(Registries.BANNER_PATTERN, BannerPatterns.class, PatternType.class).allowDirect().apiRegistryBuilder(BannerPatternRegistryEntry.Builder.class, "PaperBannerPatternRegistryEntry.PaperBuilder").delayed(), entry(Registries.PAINTING_VARIANT, PaintingVariants.class, Art.class).allowDirect().apiRegistryBuilder(PaintingVariantRegistryEntry.Builder.class, "PaperPaintingVariantRegistryEntry.PaperBuilder").apiRegistryField("ART").delayed(), entry(Registries.INSTRUMENT, Instruments.class, MusicInstrument.class).allowDirect().delayed(), - entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).delayed(), - entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).delayed(), - entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class), - entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class), - entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class) + entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).apiRegistryBuilder(CatTypeRegistryEntry.Builder.class, "PaperCatTypeRegistryEntry.PaperBuilder").delayed(), + entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).apiRegistryBuilder(FrogVariantRegistryEntry.Builder.class, "PaperFrogVariantRegistryEntry.PaperBuilder").delayed(), + entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class).apiRegistryBuilder(ChickenVariantRegistryEntry.Builder.class, "PaperChickenVariantRegistryEntry.PaperBuilder"), + entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class).apiRegistryBuilder(CowVariantRegistryEntry.Builder.class, "PaperCowVariantRegistryEntry.PaperBuilder"), + entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class).apiRegistryBuilder(PigVariantRegistryEntry.Builder.class, "PaperPigVariantRegistryEntry.PaperBuilder") ); public static final List> API_ONLY = List.of( diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index bce275705..64e5f530e 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -15,7 +15,7 @@ plugins { val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" dependencies { - mache("io.papermc:mache:1.21.5+build.1") + mache("io.papermc:mache:1.21.5+build.2") paperclip("io.papermc:paperclip:3.0.3") testRuntimeOnly("org.junit.platform:junit-platform-launcher") } @@ -135,7 +135,7 @@ dependencies { 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 implementation("net.minecrell:terminalconsoleappender:1.3.0") - implementation("io.papermc.adventure:adventure-text-serializer-ansi:4.21.0-mc1215-SNAPSHOT") // Keep in sync with adventureVersion from Paper-API build file // FIXME back to release + implementation("net.kyori:adventure-text-serializer-ansi:4.21.0") // Keep in sync with adventureVersion from Paper-API build file runtimeConfiguration(sourceSets.main.map { it.runtimeClasspath }) /* diff --git a/paper-server/patches/features/0004-Anti-Xray.patch b/paper-server/patches/features/0004-Anti-Xray.patch index 16f93f288..75d6f68cf 100644 --- a/paper-server/patches/features/0004-Anti-Xray.patch +++ b/paper-server/patches/features/0004-Anti-Xray.patch @@ -143,7 +143,7 @@ index 3a384175f8e7f204234bbaf3081bdc20c47a0d4b..5699bc15eba92e22433a20cb8326b59f private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buffer) { diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index ef201f4add358fbf1818f3b2ec9e75fe2cce4c8b..fe9b4484d683fe48f435a053c9c90557fdf80e7b 100644 +index 6b67cc939851745718f919488c997eb6719a16fc..085040aa98704f2874bcd95b751b0a81dcdb15ad 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -343,7 +343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -186,7 +186,7 @@ index 342bc843c384761e883de861044f4f8930ae8763..14878690a88fd4de3e2c127086607e6c if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), packetListener.getPlayer().getBukkitEntity()).callEvent(); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index a2a4dbcfb77d44657b3dfbe97cb629de215c29eb..73717609fccd9af12e2cc39824106f49426b581c 100644 +index 9b2ee3e16e2c443e8ff03faec59dd55d729e9274..5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -407,7 +407,7 @@ public abstract class PlayerList { @@ -199,7 +199,7 @@ index a2a4dbcfb77d44657b3dfbe97cb629de215c29eb..73717609fccd9af12e2cc39824106f49 } // Paper end - Send empty chunk diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 1f26826b2161cfeb27e5b2060e178b493e9142d9..63f8b0c47e3321b74f4b6bcbc1e28cd751911198 100644 +index 1bb40f18b671d63719d96a58ff283767c2cfe383..ba50f21707a69bbf720345996d7c83d2064e5246 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -132,6 +132,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @@ -209,10 +209,10 @@ index 1f26826b2161cfeb27e5b2060e178b493e9142d9..63f8b0c47e3321b74f4b6bcbc1e28cd7 + public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray private final CraftWorld world; public boolean pvpMode; - public org.bukkit.generator.ChunkGenerator generator; + public @Nullable org.bukkit.generator.ChunkGenerator generator; @@ -201,7 +202,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl - org.bukkit.generator.BiomeProvider biomeProvider, // CraftBukkit - org.bukkit.World.Environment env, // CraftBukkit + @Nullable org.bukkit.generator.BiomeProvider biomeProvider, // Paper + org.bukkit.World.Environment environment, // Paper java.util.function.Function paperWorldConfigCreator // Paper - create paper world config + io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, // Paper - create paper world config diff --git a/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch index 0a8480644..49514101c 100644 --- a/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch @@ -3874,10 +3874,10 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java new file mode 100644 -index 0000000000000000000000000000000000000000..7554c109c35397bc1a43dd80e87764fd78645bbf +index 0000000000000000000000000000000000000000..2d24d03bbdb5ee0d862cbfff2219f58afffafe12 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java -@@ -0,0 +1,1002 @@ +@@ -0,0 +1,1006 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + +import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable; @@ -4059,6 +4059,10 @@ index 0000000000000000000000000000000000000000..7554c109c35397bc1a43dd80e87764fd + } + } + ++ public Iterable getAllMapped() { ++ return this.entityByUUID.values(); ++ } ++ + public int getEntityCount() { + synchronized (this.accessibleEntities) { + return this.accessibleEntities.size(); @@ -26798,7 +26802,7 @@ index c50a1a01d167696134bd65b2d28db323d81d6ebd..5d63bf024cbcbd2f627c64fee77553c9 } } diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index 3f83a589442a80e9c16b5e9cd0f50792defd12bc..0005a1784ccaa00e5d6d67e7be98445150487982 100644 +index 69fbcd734c269bbc9858b0ad0b3b268ddb81fcc6..a1ae77b70f69852d9e4332bf1cb3409c33b21de0 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java @@ -104,6 +104,11 @@ public class ServerEntity { @@ -26814,7 +26818,7 @@ index 3f83a589442a80e9c16b5e9cd0f50792defd12bc..0005a1784ccaa00e5d6d67e7be984451 if (!passengers.equals(this.lastPassengers)) { List list = this.mountedOrDismounted(passengers).map(Entity::getUUID).toList(); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index fe9b4484d683fe48f435a053c9c90557fdf80e7b..8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee 100644 +index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8813846a6 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -166,7 +166,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; @@ -27565,10 +27569,10 @@ index fe9b4484d683fe48f435a053c9c90557fdf80e7b..8afe96bfdc37e57129f1bb4af5b6d5cc } diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index a8c73bdf8fb130eed8922cb537a35cda07e66da5..3e73c69c9db8cbded28a001b20d9989acb11c638 100644 +index 57af8cd7629fa14176c6e7a29956617ec9506999..63fecebe6048b0d3372ea84ac74dc74744de3273 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -187,7 +187,7 @@ import net.minecraft.world.scores.Team; +@@ -186,7 +186,7 @@ import net.minecraft.world.scores.Team; import net.minecraft.world.scores.criteria.ObjectiveCriteria; import org.slf4j.Logger; @@ -27577,7 +27581,7 @@ index a8c73bdf8fb130eed8922cb537a35cda07e66da5..3e73c69c9db8cbded28a001b20d9989a private static final Logger LOGGER = LogUtils.getLogger(); private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; -@@ -423,6 +423,36 @@ public class ServerPlayer extends Player { +@@ -415,6 +415,36 @@ public class ServerPlayer extends Player { 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 @@ -28202,10 +28206,10 @@ index b30f56fbc1fd17259a1d05dc9155fffcab292ca1..11fed81a4696ba18440e755c3b8a5ca3 this.generatingStep = generatingStep; this.cache = cache; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8..78201407a37eced73998b97d5d5c412eaba69af1 100644 +index eda176c96bcf3d67650722ffce33863edfbdea9e..a7a07ebe6ceed99fa768b6834e350fe2f51a6950 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -1320,7 +1320,7 @@ public abstract class PlayerList { +@@ -1332,7 +1332,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -28214,7 +28218,7 @@ index 5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8..78201407a37eced73998b97d5d5c412e for (ServerLevel serverLevel : this.server.getAllLevels()) { if (serverLevel != null) { -@@ -1331,7 +1331,7 @@ public abstract class PlayerList { +@@ -1343,7 +1343,7 @@ public abstract class PlayerList { public void setSimulationDistance(int simulationDistance) { this.simulationDistance = simulationDistance; @@ -28597,7 +28601,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896 + // Paper end - block counting } diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e36b7294f 100644 +index 663fb13233afb51f935c30ac2acae808809754c6..81a18b8e605bd4c28b48a32c80be231609182970 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -140,7 +140,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -28950,7 +28954,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e } private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { -@@ -2599,21 +2747,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2616,21 +2764,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -29072,7 +29076,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4061,15 +4298,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4078,15 +4315,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -29098,7 +29102,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e } public int countPlayerPassengers() { -@@ -4212,77 +4451,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4229,77 +4468,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(partialTick, this.yRotO, this.yRot); } @@ -29289,7 +29293,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e public boolean touchingUnloadedChunk() { AABB aabb = this.getBoundingBox().inflate(1.0); -@@ -4437,6 +4735,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4454,6 +4752,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29305,7 +29309,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e if (!checkPosition(this, x, y, z)) { return; } -@@ -4570,6 +4877,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4587,6 +4894,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason removalReason, @Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { // CraftBukkit - add Bukkit remove cause @@ -29318,7 +29322,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers if (this.removalReason == null) { -@@ -4580,7 +4893,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4597,7 +4910,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29327,7 +29331,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e this.levelCallback.onRemove(removalReason); this.onRemoval(removalReason); // Paper start - Folia schedulers -@@ -4614,7 +4927,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4631,7 +4944,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() @@ -29576,7 +29580,7 @@ index b766b4281aecb3b96e2c263664d81da3425e3653..c3bcb494afe464207e805f8c40b03c70 this(setDirty, true, ImmutableList.of()); } diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java -index 75bf15ccd8a12153951f886ed87be9f3bece3133..6f601a0a300bbf01f77d835576d15e25c8ba10b8 100644 +index f5ce8151bb1bae9be638ced7f74899d452d517e1..5248f3c22abb608d7d7b338f169f13bfbf4cd2d6 100644 --- a/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/net/minecraft/world/entity/decoration/ArmorStand.java @@ -245,7 +245,7 @@ public class ArmorStand extends LivingEntity { @@ -29725,7 +29729,7 @@ index 300f3ed58109219d97846082941b860585f66fed..892a7c1eb1b321ca6d5ca709142e7fea // Paper start - Affects Spawning API diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 63f8b0c47e3321b74f4b6bcbc1e28cd751911198..eb4d03cfdb34243901cfba832d35559d5be9e876 100644 +index ba50f21707a69bbf720345996d7c83d2064e5246..e9751a95ffd88f365185d53f8764291d9d2473e2 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -81,6 +81,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -30399,7 +30403,7 @@ index 63f8b0c47e3321b74f4b6bcbc1e28cd751911198..eb4d03cfdb34243901cfba832d35559d + // Paper end - getblock optimisations - cache world height/sections this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config - this.generator = gen; + this.generator = generator; @@ -281,6 +914,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl }); // CraftBukkit end diff --git a/paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch b/paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch index ba97d07c8..ae7d01be8 100644 --- a/paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch +++ b/paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch @@ -50,7 +50,7 @@ index 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921d ProfilerFiller profilerFiller = Profiler.get(); this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings) diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e..d50d2928ad9f8b34a14621b1fe5c188547e04bd1 100644 +index 32c8d4675de341d5edad7dbd9c0bf4bce5037733..bfbfbaa9660d21071c420b60b10be0a02a1bc87e 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -1317,6 +1317,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -64,7 +64,7 @@ index 32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e..d50d2928ad9f8b34a14621b1fe5c1885 + } + + if (doFull) { -+ this.saveLevelData(true); ++ this.saveLevelData(false); + } + // chunk autosave is already called by the ChunkSystem during unload processing (ChunkMap#processUnloads) + // Copied from save() @@ -83,10 +83,10 @@ index 32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e..d50d2928ad9f8b34a14621b1fe5c1885 // Paper start - add close param this.save(progress, flush, skipSave, false); diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 3e73c69c9db8cbded28a001b20d9989acb11c638..d1de5aff81da465be79f2f747466734e80ec50dc 100644 +index 5a60f2598560571e156612bf256c1c340d92a922..57e7d0a8b5f2a5bc65b0f290fb655625b1481f31 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -189,6 +189,7 @@ import org.slf4j.Logger; +@@ -188,6 +188,7 @@ import org.slf4j.Logger; public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system private static final Logger LOGGER = LogUtils.getLogger(); @@ -95,7 +95,7 @@ index 3e73c69c9db8cbded28a001b20d9989acb11c638..d1de5aff81da465be79f2f747466734e private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; private static final int FLY_STAT_RECORDING_SPEED = 25; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 78201407a37eced73998b97d5d5c412eaba69af1..f057e682ccd378f11710dc2e7129cba95788bb18 100644 +index a7a07ebe6ceed99fa768b6834e350fe2f51a6950..9ca3c55a3b5b1a532b86b08eb92460df4cb54f2a 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -486,6 +486,7 @@ public abstract class PlayerList { @@ -106,7 +106,7 @@ index 78201407a37eced73998b97d5d5c412eaba69af1..f057e682ccd378f11710dc2e7129cba9 this.playerIo.save(player); ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit if (serverStatsCounter != null) { -@@ -1067,9 +1068,23 @@ public abstract class PlayerList { +@@ -1079,9 +1080,23 @@ public abstract class PlayerList { } public void saveAll() { diff --git a/paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch b/paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch index 7cbbacf8b..b521f05eb 100644 --- a/paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch +++ b/paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch @@ -78,10 +78,10 @@ index 5d63bf024cbcbd2f627c64fee77553c9a512bd15..f863377a807b672f49f7140688f378ec profiler.popPush("tickSpawningChunks"); diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 8e7ee4dc951eb53ccf65ab71214a0b89bd932ba0..73a450e045eba5dbfc7a4e861e4c614c8f60d6b4 100644 +index 4b2801749328f250ce5735fbe7f6941a6bede01a..af04fcdba1e57b4eac678235b56ad3e1c70169b7 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -403,6 +403,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -395,6 +395,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc public boolean queueHealthUpdatePacket; public @Nullable net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; // Paper end - cancellable death event diff --git a/paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index 46cd1a1a5..0f67c9da6 100644 --- a/paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -60,10 +60,10 @@ index f863377a807b672f49f7140688f378eca2cf650b..59e8a5e1b35c81883c9b1ca00c6e55d7 spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); } else { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 73a450e045eba5dbfc7a4e861e4c614c8f60d6b4..105d6b3a40067f9e8ae5bbd9f2872171f73b3d07 100644 +index af04fcdba1e57b4eac678235b56ad3e1c70169b7..3781d9cc174b7aecacb9b9855d52c7b1ff05835c 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -407,6 +407,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -399,6 +399,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length; public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper end - Optional per player mob spawns @@ -72,7 +72,7 @@ index 73a450e045eba5dbfc7a4e861e4c614c8f60d6b4..105d6b3a40067f9e8ae5bbd9f2872171 public org.bukkit.craftbukkit.entity.CraftPlayer.TransferCookieConnection transferCookieConnection; public String displayName; diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java -index 17b13baa3465530b11ff918c806c772eb5c39a2c..afd6da5c361e1dcf311a9afe8a7efe2faef2556a 100644 +index c710e08ab48075ce7854e56826adb8f0364b025b..14a2514a408a66a83f7b5fb43b4c4dc8f23fd5f4 100644 --- a/net/minecraft/world/level/NaturalSpawner.java +++ b/net/minecraft/world/level/NaturalSpawner.java @@ -279,6 +279,11 @@ public final class NaturalSpawner { diff --git a/paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch b/paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch index 8dce7a440..b00faac56 100644 --- a/paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimise collision checking in player move packet handling Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062b48d43fa 100644 +index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a195b8302 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -555,7 +555,7 @@ public class ServerGamePacketListenerImpl @@ -88,7 +88,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062 } @Override -@@ -1430,7 +1462,7 @@ public class ServerGamePacketListenerImpl +@@ -1432,7 +1464,7 @@ public class ServerGamePacketListenerImpl } } @@ -97,7 +97,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062 d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above -@@ -1469,6 +1501,7 @@ public class ServerGamePacketListenerImpl +@@ -1471,6 +1503,7 @@ public class ServerGamePacketListenerImpl boolean flag1 = this.player.verticalCollisionBelow; this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move @@ -105,7 +105,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062 // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1501,7 +1534,17 @@ public class ServerGamePacketListenerImpl +@@ -1503,7 +1536,17 @@ public class ServerGamePacketListenerImpl } // Paper start - Add fail move event @@ -124,7 +124,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062 if (teleportBack) { io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK, toX, toY, toZ, toYaw, toPitch, false); -@@ -1638,7 +1681,7 @@ public class ServerGamePacketListenerImpl +@@ -1640,7 +1683,7 @@ public class ServerGamePacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -133,7 +133,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062 this.awaitingTeleportTime = this.tickCount; this.teleport( this.awaitingPositionFromClient.x, -@@ -1657,6 +1700,33 @@ public class ServerGamePacketListenerImpl +@@ -1659,6 +1702,33 @@ public class ServerGamePacketListenerImpl } } diff --git a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch index f892ceeba..1254bdfc9 100644 --- a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch +++ b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch @@ -13,7 +13,7 @@ + public CommandNode clientNode; // Paper - Brigadier API + public CommandNode unwrappedCached = null; // Paper - Brigadier Command API + public CommandNode wrappedCached = null; // Paper - Brigadier Command API -+ public io.papermc.paper.command.brigadier.PluginCommandMeta pluginCommandMeta; // Paper - Brigadier Command API ++ public io.papermc.paper.command.brigadier.APICommandMeta apiCommandMeta; // Paper - Brigadier Command API + // CraftBukkit start + public void removeCommand(String name) { + this.children.remove(name); diff --git a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch index 440074ebe..24a2b69e5 100644 --- a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch @@ -172,7 +172,7 @@ } return null; -@@ -359,26 +_,120 @@ +@@ -359,26 +_,121 @@ } public void sendCommands(ServerPlayer player) { @@ -252,6 +252,7 @@ + } + // Paper end - Brigadier API + if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot ++ if (commandNode.wrappedCached != null && commandNode.wrappedCached.apiCommandMeta != null && commandNode.wrappedCached.apiCommandMeta.serverSideOnly()) continue; // Paper if (commandNode.canUse(source)) { ArgumentBuilder argumentBuilder = (ArgumentBuilder) commandNode.createBuilder(); + // Paper start diff --git a/paper-server/patches/sources/net/minecraft/core/ClientAsset.java.patch b/paper-server/patches/sources/net/minecraft/core/ClientAsset.java.patch new file mode 100644 index 000000000..3f686beec --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/core/ClientAsset.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/core/ClientAsset.java ++++ b/net/minecraft/core/ClientAsset.java +@@ -12,6 +_,6 @@ + public static final StreamCodec STREAM_CODEC = StreamCodec.composite(ResourceLocation.STREAM_CODEC, ClientAsset::id, ClientAsset::new); + + public ClientAsset(ResourceLocation id) { +- this(id, id.withPath(string -> "textures/" + string + ".png")); ++ this(id, id.withPath(string -> "textures/" + string + ".png")); // Paper - diff on change - io.papermc.paper.registry.data.client.ClientAssetImpl#pathFromIdentifier + } + } diff --git a/paper-server/patches/sources/net/minecraft/network/HashedStack.java.patch b/paper-server/patches/sources/net/minecraft/network/HashedStack.java.patch deleted file mode 100644 index 8f72f1fe5..000000000 --- a/paper-server/patches/sources/net/minecraft/network/HashedStack.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/network/HashedStack.java -+++ b/net/minecraft/network/HashedStack.java -@@ -17,7 +_,7 @@ - } - - @Override -- public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) { -+ public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic - return stack.isEmpty(); - } - }; -@@ -27,7 +_,7 @@ - hashedStack -> hashedStack instanceof HashedStack.ActualItem actualItem ? Optional.of(actualItem) : Optional.empty() - ); - -- boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator); -+ boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching); // Paper - add flag to simplify remote matching logic - - static HashedStack create(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) { - return (HashedStack)(stack.isEmpty() -@@ -47,10 +_,10 @@ - ); - - @Override -- public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) { -+ public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic - return this.count == stack.getCount() - && this.item.equals(stack.getItemHolder()) -- && this.components.matches(stack.getComponentsPatch(), hashGenerator); -+ && (simplifyMatching || this.components.matches(stack.getComponentsPatch(), hashGenerator)); // Paper - add flag to simplify remote matching logic - } - } - } diff --git a/paper-server/patches/sources/net/minecraft/network/syncher/EntityDataSerializers.java.patch b/paper-server/patches/sources/net/minecraft/network/syncher/EntityDataSerializers.java.patch new file mode 100644 index 000000000..683b68fe2 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/network/syncher/EntityDataSerializers.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/network/syncher/EntityDataSerializers.java ++++ b/net/minecraft/network/syncher/EntityDataSerializers.java +@@ -51,10 +_,27 @@ + public static final EntityDataSerializer> OPTIONAL_COMPONENT = EntityDataSerializer.forValueType( + ComponentSerialization.TRUSTED_OPTIONAL_STREAM_CODEC + ); ++ // Paper start - do not obfuscate items sent as entity data ++ public static final StreamCodec OVERSIZED_ITEM_CODEC = new net.minecraft.network.codec.StreamCodec<>() { ++ @Override ++ public net.minecraft.world.item.ItemStack decode(final net.minecraft.network.RegistryFriendlyByteBuf buffer) { ++ return ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer); ++ } ++ ++ @Override ++ public void encode(final net.minecraft.network.RegistryFriendlyByteBuf buffer, final net.minecraft.world.item.ItemStack value) { ++ // If the codec is called during an obfuscation session, downgrade the context's obf level to OVERSIZED if it isn't already. ++ // Entity data cannot be fully obfuscated as entities might render out specific values (e.g. count or custom name). ++ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.level(io.papermc.paper.util.sanitizer.ItemObfuscationSession.ObfuscationLevel.OVERSIZED))) { ++ ItemStack.OPTIONAL_STREAM_CODEC.encode(buffer, value); ++ } ++ } ++ }; ++ // Paper end - do not obfuscate items sent as entity data + public static final EntityDataSerializer ITEM_STACK = new EntityDataSerializer() { + @Override + public StreamCodec codec() { +- return ItemStack.OPTIONAL_STREAM_CODEC; ++ return OVERSIZED_ITEM_CODEC; // Paper - do not obfuscate items sent as entity data + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/server/ReloadableServerResources.java.patch b/paper-server/patches/sources/net/minecraft/server/ReloadableServerResources.java.patch index caa71bc36..164b4a459 100644 --- a/paper-server/patches/sources/net/minecraft/server/ReloadableServerResources.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/ReloadableServerResources.java.patch @@ -1,12 +1,13 @@ --- a/net/minecraft/server/ReloadableServerResources.java +++ b/net/minecraft/server/ReloadableServerResources.java -@@ -38,7 +_,8 @@ +@@ -38,7 +_,9 @@ this.fullRegistryHolder = new ReloadableServerRegistries.Holder(registryAccess.compositeAccess()); this.postponedTags = postponedTags; this.recipes = new RecipeManager(registries); - this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures)); + this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures), true); // Paper - Brigadier Command API - use modern alias registration + io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setDispatcher(this.commands, CommandBuildContext.simple(registries, enabledFeatures)); // Paper - Brigadier Command API ++ io.papermc.paper.command.PaperCommands.registerCommands(); // Paper this.advancements = new ServerAdvancementManager(registries); this.functionLibrary = new ServerFunctionLibrary(functionCompilationLevel, this.commands.getDispatcher()); } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index a19f70a25..9470cf950 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -1,5 +1,13 @@ --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java +@@ -65,7 +_,6 @@ + import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; + import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket; + import net.minecraft.network.protocol.game.ClientboundOpenBookPacket; +-import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; + import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; + import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; + import net.minecraft.network.protocol.game.ClientboundPlayerCombatEndPacket; @@ -235,7 +_,8 @@ private int levitationStartTime; private boolean disconnected; @@ -10,7 +18,7 @@ @Nullable private Vec3 startingToFallPosition; @Nullable -@@ -281,6 +_,20 @@ +@@ -281,6 +_,13 @@ } } @@ -20,26 +28,10 @@ + ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(ServerPlayer.this.inventoryMenu.containerId, ServerPlayer.this.inventoryMenu.incrementStateId(), net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT, ServerPlayer.this.inventoryMenu.getSlot(net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT).getItem().copy())); + } + // Paper end - Sync offhand slot in menus -+ -+ // Paper start - add flag to simplify remote matching logic -+ @Override -+ public ServerPlayer player() { -+ return ServerPlayer.this; -+ } -+ // Paper end - add flag to simplify remote matching logic + @Override public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) { ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slot, itemStack)); -@@ -302,7 +_,7 @@ - - @Override - public RemoteSlot createSlot() { -- return new RemoteSlot.Synchronized(this.cache::getUnchecked); -+ return new RemoteSlot.Synchronized(this.cache::getUnchecked, ServerPlayer.this.getBukkitEntity().simplifyContainerDesyncCheck()); // Paper - add flag to simplify remote matching logic - } - }; - private final ContainerListener containerListener = new ContainerListener() { @@ -316,6 +_,32 @@ } } @@ -316,12 +308,19 @@ } float saturationLevel = this.foodData.getSaturationLevel(); -@@ -793,15 +_,84 @@ +@@ -793,15 +_,36 @@ } private void updateScoreForCriteria(ObjectiveCriteria criteria, int points) { - this.getScoreboard().forAllObjectives(criteria, this, score -> score.set(points)); - } +- +- @Override +- public void die(DamageSource cause) { +- this.gameEvent(GameEvent.ENTITY_DIE); +- boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); +- if (_boolean) { +- Component deathMessage = this.getCombatTracker().getDeathMessage(); + this.level().getCraftServer().getScoreboardManager().forAllObjectives(criteria, this, score -> score.set(points)); // CraftBukkit - Use our scores instead + } + @@ -348,13 +347,24 @@ + return false; + } + // Paper end - PlayerDeathEvent#getItemsToKeep - - @Override - public void die(DamageSource cause) { -- this.gameEvent(GameEvent.ENTITY_DIE); -- boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); -- if (_boolean) { -- Component deathMessage = this.getCombatTracker().getDeathMessage(); ++ // Paper start - Expand PlayerDeathEvent API ++ private void sendClientboundPlayerCombatKillPacket(boolean displayMessage, Component deathMessage) { ++ if (displayMessage && deathMessage != CommonComponents.EMPTY) { ++ // Paper - moved from below die(DamageSource) method + this.connection + .send( + new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage), +@@ -818,6 +_,65 @@ + } + ) + ); ++ } else { ++ this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), CommonComponents.EMPTY)); ++ } ++ } ++ // Paper end - Expand PlayerDeathEvent API ++ @Override ++ public void die(DamageSource cause) { + // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check + boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); final boolean showDeathMessage = _boolean; // Paper - OBFHELPER + // CraftBukkit start - fire PlayerDeathEvent @@ -382,7 +392,7 @@ + + String deathmessage = defaultMessage.getString(); + this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel -+ org.bukkit.event.entity.PlayerDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerDeathEvent(this, cause, loot, io.papermc.paper.adventure.PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure ++ org.bukkit.event.entity.PlayerDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerDeathEvent(this, cause, loot, io.papermc.paper.adventure.PaperAdventure.asAdventure(defaultMessage), showDeathMessage, keepInventory); // Paper - Adventure; Expand PlayerDeathEvent API + // Paper start - cancellable death event + if (event.isCancelled()) { + // make compatible with plugins that might have already set the health in an event listener @@ -400,13 +410,25 @@ + } + + net.kyori.adventure.text.Component apiDeathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure ++ Component deathScreenMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(event.deathScreenMessageOverride() != null ? event.deathScreenMessageOverride() : apiDeathMessage); // Paper - Expand PlayerDeathEvent API + -+ if (apiDeathMessage != null && apiDeathMessage != net.kyori.adventure.text.Component.empty() && showDeathMessage) { // Paper - Adventure // TODO: allow plugins to override? ++ if (apiDeathMessage != null && apiDeathMessage != net.kyori.adventure.text.Component.empty() && event.getShowDeathMessages()) { // Paper - Adventure; Expand PlayerDeathEvent API + Component deathMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(apiDeathMessage); // Paper - Adventure + - this.connection - .send( - new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage), ++ // Paper - moved up to sendClientboundPlayerCombatKillPacket() ++ sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent + Team team = this.getTeam(); + if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) { + this.server.getPlayerList().broadcastSystemMessage(deathMessage, false); +@@ -827,7 +_,7 @@ + this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, deathMessage); + } + } else { +- this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), CommonComponents.EMPTY)); ++ sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent + } + + this.removeEntitiesOnShoulder(); @@ -835,11 +_,35 @@ this.tellNeutralMobsThatIDied(); } @@ -491,7 +513,7 @@ } } -@@ -914,23 +_,82 @@ +@@ -914,23 +_,77 @@ } private boolean isPvpAllowed() { @@ -541,18 +563,13 @@ + ); + + // Paper start - respawn flags -+ com.google.common.collect.ImmutableSet.Builder builder = com.google.common.collect.ImmutableSet.builder(); -+ if (respawnReason == org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.END_PORTAL) { -+ builder.add(org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag.END_PORTAL); -+ } + org.bukkit.event.player.PlayerRespawnEvent respawnEvent = new org.bukkit.event.player.PlayerRespawnEvent( + respawnPlayer, + location, + isBedSpawn, + isAnchorSpawn, + teleportTransition.missingRespawnBlock(), -+ respawnReason, -+ builder ++ respawnReason + ); + // Paper end - respawn flags + this.level().getCraftServer().getPluginManager().callEvent(respawnEvent); diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 892544dc0..4ae0a3e92 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -523,7 +523,7 @@ this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); } else { BaseCommandBlock commandBlock = packet.getCommandBlock(this.player.level()); -@@ -661,7 +_,7 @@ +@@ -661,11 +_,11 @@ boolean flag = this.player.hasInfiniteMaterials() && packet.includeData(); ItemStack cloneItemStack = blockState.getCloneItemStack(serverLevel, blockPos, flag); if (!cloneItemStack.isEmpty()) { @@ -532,7 +532,23 @@ addBlockDataToItem(blockState, serverLevel, blockPos, cloneItemStack); } -@@ -698,18 +_,29 @@ +- this.tryPickItem(cloneItemStack); ++ this.tryPickItem(cloneItemStack, blockPos, null, packet.includeData()); // Paper - Extend PlayerPickItemEvent API + } + } + } +@@ -689,27 +_,40 @@ + if (entityOrPart != null && this.player.canInteractWithEntity(entityOrPart, 3.0)) { + ItemStack pickResult = entityOrPart.getPickResult(); + if (pickResult != null && !pickResult.isEmpty()) { +- this.tryPickItem(pickResult); ++ this.tryPickItem(pickResult, null, entityOrPart, packet.includeData()); // Paper - Extend PlayerPickItemEvent API + } + } + } + +- private void tryPickItem(ItemStack stack) { ++ private void tryPickItem(ItemStack stack, @Nullable BlockPos blockPos, @Nullable Entity entity, boolean includeData) { // Paper - Extend PlayerPickItemEvent API if (stack.isItemEnabled(this.player.level().enabledFeatures())) { Inventory inventory = this.player.getInventory(); int i = inventory.findSlotMatchingItem(stack); @@ -540,7 +556,9 @@ + final int sourceSlot = i; + final int targetSlot = Inventory.isHotbarSlot(sourceSlot) ? sourceSlot : inventory.getSuitableHotbarSlot(); + final org.bukkit.entity.Player bukkitPlayer = this.player.getBukkitEntity(); -+ final io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot); ++ final io.papermc.paper.event.player.PlayerPickItemEvent event = entity != null ++ ? new io.papermc.paper.event.player.PlayerPickEntityEvent(bukkitPlayer, entity.getBukkitEntity(), includeData, targetSlot, sourceSlot) ++ : new io.papermc.paper.event.player.PlayerPickBlockEvent(bukkitPlayer, org.bukkit.craftbukkit.block.CraftBlock.at(this.player.level(), blockPos), includeData, targetSlot, sourceSlot); + if (!event.callEvent()) { + return; + } @@ -2468,7 +2486,7 @@ } else if (flag && flag2) { if (this.dropSpamThrottler.isUnderThreshold()) { this.dropSpamThrottler.increment(); -@@ -1895,11 +_,24 @@ +@@ -1895,15 +_,38 @@ @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { @@ -2494,6 +2512,20 @@ this.player.resetLastActionTime(); ServerLevel serverLevel = this.player.serverLevel(); BlockPos pos = packet.getPos(); + if (serverLevel.hasChunkAt(pos)) { ++ // Paper start - Add API for client-side signs ++ if (!new io.papermc.paper.event.packet.UncheckedSignChangeEvent( ++ this.player.getBukkitEntity(), ++ io.papermc.paper.util.MCUtil.toPosition(pos), ++ packet.isFrontText() ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK, ++ filteredText.stream().map(line -> net.kyori.adventure.text.Component.text(line.raw())).toList()) ++ .callEvent()) { ++ return; ++ } ++ // Paper end - Add API for client-side signs + if (!(serverLevel.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity)) { + return; + } @@ -1915,14 +_,32 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) { diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch index e373ebb46..abd87f554 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch @@ -9,10 +9,10 @@ + static final java.util.regex.Pattern HOST_PATTERN = java.util.regex.Pattern.compile("[0-9a-f\\.:]{0,45}"); + static final java.util.regex.Pattern PROP_PATTERN = java.util.regex.Pattern.compile("\\w{0,16}"); + // Spigot end -+ // CraftBukkit start - add fields -+ private static final java.util.HashMap throttleTracker = new java.util.HashMap<>(); ++ // Paper start - Connection throttle ++ private static final java.util.Map throttleTracker = new java.util.HashMap<>(); + private static int throttleCounter = 0; -+ // CraftBukkit end ++ // Paper end - Connection throttle + private static final boolean BYPASS_HOSTCHECK = Boolean.getBoolean("Paper.bypassHostCheck"); // Paper private final MinecraftServer server; private final Connection connection; @@ -29,7 +29,7 @@ switch (packet.intention()) { case LOGIN: this.beginLogin(packet, false); -@@ -50,22 +_,117 @@ +@@ -50,22 +_,118 @@ default: throw new UnsupportedOperationException("Invalid intention " + packet.intention()); } @@ -42,17 +42,18 @@ private void beginLogin(ClientIntentionPacket packet, boolean transferred) { this.connection.setupOutboundProtocol(LoginProtocols.CLIENTBOUND); -+ // CraftBukkit start - Connection throttle ++ // Paper start - Connection throttle + try { -+ if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket ++ final long connectionThrottle = this.server.server.getConnectionThrottle(); ++ final boolean isUnixDomainSocket = this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress; // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket ++ if (connectionThrottle > 0 && !isUnixDomainSocket && this.connection.getRemoteAddress() instanceof java.net.InetSocketAddress socketAddress && !socketAddress.isUnresolved() && !socketAddress.getAddress().isLoopbackAddress()) { + long currentTime = System.currentTimeMillis(); -+ long connectionThrottle = this.server.server.getConnectionThrottle(); -+ java.net.InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress(); ++ java.net.InetAddress address = socketAddress.getAddress(); + + synchronized (ServerHandshakePacketListenerImpl.throttleTracker) { -+ if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) { ++ if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) { + ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime); -+ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message ++ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); + this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); + this.connection.disconnect(chatmessage); + return; @@ -67,11 +68,11 @@ + ServerHandshakePacketListenerImpl.throttleTracker.values().removeIf(time -> time > connectionThrottle); + } + } -+ } // Paper - Unix domain socket support ++ } + } catch (Throwable t) { + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); + } -+ // CraftBukkit end ++ // Paper end - Connection throttle if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) { - Component component; - if (packet.protocolVersion() < 754) { diff --git a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch index 04c85d3a4..5309bf10a 100644 --- a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch @@ -524,7 +524,7 @@ IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress); MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason()); if (ipBanListEntry.getExpires() != null) { -@@ -381,69 +_,130 @@ +@@ -381,69 +_,131 @@ ); } @@ -649,6 +649,7 @@ + // Paper start - Add PlayerPostRespawnEvent + boolean isBedSpawn = false; + boolean isRespawn = false; ++ boolean isAnchorSpawn = false; + // Paper end - Add PlayerPostRespawnEvent + + // CraftBukkit start - fire PlayerRespawnEvent @@ -714,13 +715,17 @@ serverPlayer.setHealth(serverPlayer.getHealth()); ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig(); if (!keepInventory && respawnConfig != null) { -@@ -477,8 +_,41 @@ +@@ -477,8 +_,52 @@ ) ); } + // Paper start - Add PlayerPostRespawnEvent -+ if (blockState.is(net.minecraft.tags.BlockTags.BEDS) && !teleportTransition.missingRespawnBlock()) { -+ isBedSpawn = true; ++ if (!teleportTransition.missingRespawnBlock()) { ++ if (blockState.is(net.minecraft.tags.BlockTags.BEDS)) { ++ isBedSpawn = true; ++ } else if (blockState.is(Blocks.RESPAWN_ANCHOR)) { ++ isAnchorSpawn = true; ++ } + } + // Paper end - Add PlayerPostRespawnEvent } @@ -748,7 +753,14 @@ + + // Paper start - Add PlayerPostRespawnEvent + if (isRespawn) { -+ cserver.getPluginManager().callEvent(new com.destroystokyo.paper.event.player.PlayerPostRespawnEvent(player.getBukkitEntity(), location, isBedSpawn)); ++ new com.destroystokyo.paper.event.player.PlayerPostRespawnEvent( ++ player.getBukkitEntity(), ++ location, ++ isBedSpawn, ++ isAnchorSpawn, ++ teleportTransition.missingRespawnBlock(), ++ eventReason ++ ).callEvent(); + } + // Paper end - Add PlayerPostRespawnEvent + diff --git a/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch b/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch index 7f97d57b1..63b5de688 100644 --- a/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch +++ b/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch @@ -1,16 +1,22 @@ --- a/net/minecraft/util/datafix/DataFixers.java +++ b/net/minecraft/util/datafix/DataFixers.java -@@ -541,6 +_,18 @@ +@@ -541,6 +_,24 @@ Schema schema44 = builder.addSchema(1456, SAME_NAMESPACED); builder.addFixer(new EntityItemFrameDirectionFix(schema44, false)); Schema schema45 = builder.addSchema(1458, V1458::new); + // CraftBukkit start -+ builder.addFixer(new com.mojang.datafixers.DataFix(schema45, false) { ++ // API allows setting player custom names, so we need to convert them. ++ // This does *not* handle upgrades in any other version, but generally those shouldn't need conversion. ++ builder.addFixer(new DataFix(schema45, false) { + @Override -+ protected com.mojang.datafixers.TypeRewriteRule makeRule() { -+ return this.fixTypeEverywhereTyped("Player CustomName", this.getInputSchema().getType(References.PLAYER), (typed) -> { -+ return typed.update(DSL.remainderFinder(), (dynamic) -> { -+ return EntityCustomNameToComponentFix.fixCustomName(dynamic.getOps(), dynamic.get("CustomName").asString(""), "minecraft:player"); ++ protected TypeRewriteRule makeRule() { ++ return this.fixTypeEverywhereTyped("Player CustomName", this.getInputSchema().getType(References.PLAYER), typed -> { ++ return typed.update(DSL.remainderFinder(), dynamic -> { ++ final String customName = dynamic.get("CustomName").asString(""); ++ if (customName.isEmpty()) { ++ return dynamic.remove("CustomName"); ++ } ++ return dynamic.set("CustomName", LegacyComponentDataFixUtils.createPlainTextComponent(dynamic.getOps(), customName)); + }); + }); + } diff --git a/paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch b/paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch new file mode 100644 index 000000000..440f7e851 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java ++++ b/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java +@@ -39,6 +_,6 @@ + .renameField("PostRaidTicks", "post_raid_ticks") + .renameField("TotalHealth", "total_health") + .renameField("NumGroups", "group_count") +- .renameField("Status", "status"); ++ .renameField("Status", "status").renameField("HeroesOfTheVillage", "heroes_of_the_village"); // Paper - Add missing rename + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/damagesource/CombatTracker.java.patch b/paper-server/patches/sources/net/minecraft/world/damagesource/CombatTracker.java.patch new file mode 100644 index 000000000..11b79f9cf --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/damagesource/CombatTracker.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/damagesource/CombatTracker.java ++++ b/net/minecraft/world/damagesource/CombatTracker.java +@@ -29,15 +_,24 @@ + private int combatEndTime; + public boolean inCombat; + public boolean takingDamage; ++ public final io.papermc.paper.world.damagesource.PaperCombatTrackerWrapper paperCombatTracker; // Paper - Combat tracker API + + public CombatTracker(LivingEntity mob) { + this.mob = mob; ++ this.paperCombatTracker = new io.papermc.paper.world.damagesource.PaperCombatTrackerWrapper(this); // Paper - Combat tracker API + } + + public void recordDamage(DamageSource source, float damage) { + this.recheckStatus(); + FallLocation currentFallLocation = FallLocation.getCurrentFallLocation(this.mob); + CombatEntry combatEntry = new CombatEntry(source, damage, currentFallLocation, (float)this.mob.fallDistance); ++ // Paper start - Combat tracker API ++ recordDamageAndCheckCombatState(combatEntry); ++ } ++ ++ public void recordDamageAndCheckCombatState(final CombatEntry combatEntry) { ++ final DamageSource source = combatEntry.source(); ++ // Paper end - Combat tracker API + this.entries.add(combatEntry); + this.lastDamageTime = this.mob.tickCount; + this.takingDamage = true; +@@ -147,6 +_,13 @@ + public void recheckStatus() { + int i = this.inCombat ? 300 : 100; + if (this.takingDamage && (!this.mob.isAlive() || this.mob.tickCount - this.lastDamageTime > i)) { ++ // Paper start - Combat tracker API ++ resetCombatState(); ++ } ++ } ++ ++ public void resetCombatState() {{ ++ // Paper end - Combat tracker API + boolean flag = this.inCombat; + this.takingDamage = false; + this.inCombat = false; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index 37f0ba306..10e24def5 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -126,6 +126,15 @@ private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0}; private long pistonDeltasGameTime; private EntityDimensions dimensions; +@@ -251,7 +_,7 @@ + private boolean onGroundNoBlocks = false; + private float crystalSoundIntensity; + private int lastCrystalSoundPlayTick; +- public boolean hasVisualFire; ++ public net.kyori.adventure.util.TriState visualFire = net.kyori.adventure.util.TriState.NOT_SET; // Paper - improve visual fire API + @Nullable + private BlockState inBlockState = null; + private final List> movementThisTick = new ObjectArrayList<>(); @@ -259,6 +_,41 @@ private final LongSet visitedBlocks = new LongOpenHashSet(); private final InsideBlockEffectApplier.StepBasedCollector insideEffectCollector = new InsideBlockEffectApplier.StepBasedCollector(); @@ -392,7 +401,12 @@ } this.checkBelowWorld(); -@@ -504,7 +_,12 @@ +@@ -500,11 +_,16 @@ + } + + public void setSharedFlagOnFire(boolean isOnFire) { +- this.setSharedFlag(0, isOnFire || this.hasVisualFire); ++ this.setSharedFlag(0, this.visualFire.toBooleanOrElse(isOnFire)); // Paper - improve visual fire API } public void checkBelowWorld() { @@ -694,7 +708,7 @@ return true; } } -@@ -1805,14 +_,34 @@ +@@ -1805,14 +_,35 @@ } public CompoundTag saveWithoutId(CompoundTag compound) { @@ -715,6 +729,7 @@ } + } // CraftBukkit ++ this.setDeltaMovement(io.papermc.paper.util.MCUtil.sanitizeNanInf(this.deltaMovement, 0D)); // Paper - remove NaN values before usage in saving compound.store("Motion", Vec3.CODEC, this.getDeltaMovement()); + // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero + // TODO: make sure this is the best way to address this. @@ -760,6 +775,21 @@ Component customName = this.getCustomName(); if (customName != null) { RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); +@@ -1848,9 +_,12 @@ + compound.putInt("TicksFrozen", this.getTicksFrozen()); + } + +- if (this.hasVisualFire) { +- compound.putBoolean("HasVisualFire", this.hasVisualFire); ++ // Paper start - improve visual fire API ++ if (this.visualFire.equals(net.kyori.adventure.util.TriState.TRUE)) { ++ compound.putBoolean("HasVisualFire", true); + } ++ compound.putString("Paper.FireOverride", visualFire.name()); ++ // Paper end + + if (!this.tags.isEmpty()) { + compound.store("Tags", TAG_LIST_CODEC, List.copyOf(this.tags)); @@ -1860,13 +_,13 @@ compound.store("data", CustomData.CODEC, this.customData); } @@ -810,6 +840,37 @@ return compound; } catch (Throwable var8) { CrashReport crashReport = CrashReport.forThrowable(var8, "Saving entity NBT"); +@@ -1888,7 +_,7 @@ + public void load(CompoundTag compound) { + try { + Vec3 vec3 = compound.read("Pos", Vec3.CODEC).orElse(Vec3.ZERO); +- Vec3 vec31 = compound.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); ++ Vec3 vec31 = compound.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); vec31 = io.papermc.paper.util.MCUtil.sanitizeNanInf(vec31, 0D); // Paper - avoid setting NaN values + Vec2 vec2 = compound.read("Rotation", Vec2.CODEC).orElse(Vec2.ZERO); + this.setDeltaMovement(Math.abs(vec31.x) > 10.0 ? 0.0 : vec31.x, Math.abs(vec31.y) > 10.0 ? 0.0 : vec31.y, Math.abs(vec31.z) > 10.0 ? 0.0 : vec31.z); + this.hasImpulse = true; +@@ -1921,7 +_,20 @@ + this.setNoGravity(compound.getBooleanOr("NoGravity", false)); + this.setGlowingTag(compound.getBooleanOr("Glowing", false)); + this.setTicksFrozen(compound.getIntOr("TicksFrozen", 0)); +- this.hasVisualFire = compound.getBooleanOr("HasVisualFire", false); ++ // Paper start - improve visual fire API ++ compound.getString("Paper.FireOverride").ifPresentOrElse( ++ override -> { ++ try { ++ this.visualFire = net.kyori.adventure.util.TriState.valueOf(override); ++ } catch (final Exception ignored) { ++ LOGGER.error("Unknown fire override {} for {}", override, this); ++ } ++ }, ++ () -> this.visualFire = compound.getBoolean("HasVisualFire") ++ .map(net.kyori.adventure.util.TriState::byBoolean) ++ .orElse(net.kyori.adventure.util.TriState.NOT_SET) ++ ); ++ // Paper end + this.customData = compound.read("data", CustomData.CODEC).orElse(CustomData.EMPTY); + this.tags.clear(); + compound.read("Tags", TAG_LIST_CODEC).ifPresent(this.tags::addAll); @@ -1932,6 +_,67 @@ } else { throw new IllegalStateException("Entity has invalid rotation"); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch index 5640424cd..295adfef5 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -97,7 +97,7 @@ Vec3 vec3 = new Vec3( this.followingPlayer.getX() - this.getX(), this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(), -@@ -161,16 +_,27 @@ +@@ -161,18 +_,29 @@ } public static void award(ServerLevel level, Vec3 pos, int amount) { @@ -124,9 +124,17 @@ private static boolean tryMergeToExisting(ServerLevel level, Vec3 pos, int amount) { + // Paper - TODO some other event for this kind of merge AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0); - int randomInt = level.getRandom().nextInt(40); +- int randomInt = level.getRandom().nextInt(40); ++ int randomInt = level.getRandom().nextInt(io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA)); // Paper - Configure how many orb groups per area List entities = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aabb, orb -> canMerge(orb, randomInt, amount)); -@@ -193,9 +_,14 @@ + if (!entities.isEmpty()) { + ExperienceOrb experienceOrb = entities.get(0); +@@ -189,13 +_,18 @@ + } + + private static boolean canMerge(ExperienceOrb orb, int amount, int other) { +- return !orb.isRemoved() && (orb.getId() - amount) % 40 == 0 && orb.getValue() == other; ++ return !orb.isRemoved() && (orb.getId() - amount) % io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA) == 0 && orb.getValue() == other; // Paper - Configure how many orbs will merge together } private void merge(ExperienceOrb orb) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch index 4e881f2b4..02c0dba9e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch @@ -198,7 +198,7 @@ } return true; -@@ -400,31 +_,34 @@ +@@ -400,31 +_,42 @@ float health = this.getHealth(); health -= damageAmount; if (health <= 0.5F) { @@ -231,13 +231,24 @@ + // this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved down for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) { - ItemStack itemStack = this.equipment.set(equipmentSlot, ItemStack.EMPTY); +- ItemStack itemStack = this.equipment.set(equipmentSlot, ItemStack.EMPTY); ++ ItemStack itemStack = this.equipment.get(equipmentSlot); // Paper - move equipment removal past event call if (!itemStack.isEmpty()) { - Block.popResource(this.level(), this.blockPosition().above(), itemStack); +- } +- } + this.drops.add(new DefaultDrop(itemStack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly} - } - } -+ return this.dropAllDeathLoot(level, damageSource); // CraftBukkit - moved from above // Paper ++ } ++ } ++ // Paper start - move equipment removal past event call ++ org.bukkit.event.entity.EntityDeathEvent event = this.dropAllDeathLoot(level, damageSource); ++ if (!event.isCancelled()) { ++ for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) { ++ this.equipment.set(equipmentSlot, ItemStack.EMPTY); ++ } ++ } ++ return event; ++ // Paper end - move equipment removal past event call } private void playBrokenSound() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch index 685060419..f90f7c515 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch @@ -48,7 +48,7 @@ double squareRoot = Math.sqrt(d * d + d2 * d2); if (this.level() instanceof ServerLevel serverLevel) { + // CraftBukkit start -+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), arrow.getPickupItem(), arrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper - improve entity shoot bow event, add arrow stack to event ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), arrow.getPickupItem(), arrow, net.minecraft.world.InteractionHand.MAIN_HAND, distanceFactor, true); // Paper - improve entity shoot bow event, add arrow stack to event + if (event.isCancelled()) { + event.getProjectile().remove(); + return; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch index 9b52c7669..363c0d10d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch @@ -56,7 +56,20 @@ this.setTarget(null); this.teleport(); } -@@ -369,11 +_,13 @@ +@@ -359,21 +_,25 @@ + AbstractThrownPotion abstractThrownPotion1 = damageSource.getDirectEntity() instanceof AbstractThrownPotion abstractThrownPotion + ? abstractThrownPotion + : null; +- if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && abstractThrownPotion1 == null) { ++ if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && abstractThrownPotion1 == null) { // Paper - EndermanEscapeEvent - diff on change - below logic relies on this path covering non-projectile damage. + boolean flag = super.hurtServer(level, damageSource, amount); + if (!(damageSource.getEntity() instanceof LivingEntity) && this.random.nextInt(10) != 0) { ++ if (this.tryEscape(damageSource.is(net.minecraft.tags.DamageTypeTags.IS_DROWNING) ? com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.DROWN : com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.CRITICAL_HIT)) { // Paper - EndermanEscapeEvent + this.teleport(); ++ } // Paper - EndermanEscapeEvent + } + + return flag; } else { boolean flag = abstractThrownPotion1 != null && this.hurtWithCleanWater(level, damageSource, abstractThrownPotion1, amount); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch index 288baed66..fd0641de0 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Illusioner.java.patch @@ -5,7 +5,7 @@ double squareRoot = Math.sqrt(d * d + d2 * d2); if (this.level() instanceof ServerLevel serverLevel) { + // Paper start - EntityShootBowEvent -+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), mobArrow.getPickupItem(), mobArrow, target.getUsedItemHand(), 0.8F, true); ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), mobArrow.getPickupItem(), mobArrow, target.getUsedItemHand(), distanceFactor, true); + if (event.isCancelled()) { + event.getProjectile().remove(); + return; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch index 5a707b3b6..92cbd9db7 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch @@ -66,7 +66,7 @@ + // CraftBukkit end + } + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTransformEvent(this, slimes, org.bukkit.event.entity.EntityTransformEvent.TransformReason.SPLIT).isCancelled()) { ++ if (!slimes.isEmpty() && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTransformEvent(this, slimes, org.bukkit.event.entity.EntityTransformEvent.TransformReason.SPLIT).isCancelled()) { // check for empty converted entities or cancel event + super.remove(reason, eventCause); // add Bukkit remove cause + return; + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch index 96b211d39..bcd4ec06f 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch @@ -42,6 +42,29 @@ return; } } else { +@@ -166,12 +_,14 @@ + if (this.currentState == FishingHook.FishHookState.FLYING) { + if (this.hookedIn != null) { + this.setDeltaMovement(Vec3.ZERO); ++ new io.papermc.paper.event.entity.FishHookStateChangeEvent((org.bukkit.entity.FishHook) getBukkitEntity(), org.bukkit.entity.FishHook.HookState.HOOKED_ENTITY).callEvent(); // Paper - Add FishHookStateChangeEvent. #HOOKED_ENTITY + this.currentState = FishingHook.FishHookState.HOOKED_IN_ENTITY; + return; + } + + if (flag) { + this.setDeltaMovement(this.getDeltaMovement().multiply(0.3, 0.2, 0.3)); ++ new io.papermc.paper.event.entity.FishHookStateChangeEvent((org.bukkit.entity.FishHook) getBukkitEntity(), org.bukkit.entity.FishHook.HookState.BOBBING).callEvent(); // Paper - Add FishHookStateChangeEvent. #BOBBING + this.currentState = FishingHook.FishHookState.BOBBING; + return; + } +@@ -184,6 +_,7 @@ + this.setPos(this.hookedIn.getX(), this.hookedIn.getY(0.8), this.hookedIn.getZ()); + } else { + this.setHookedEntity(null); ++ new io.papermc.paper.event.entity.FishHookStateChangeEvent((org.bukkit.entity.FishHook) getBukkitEntity(), org.bukkit.entity.FishHook.HookState.UNHOOKED).callEvent(); // Paper - Add FishHookStateChangeEvent. #UNHOOKED + this.currentState = FishingHook.FishHookState.FLYING; + } + } @@ -247,14 +_,14 @@ if (!player.isRemoved() && player.isAlive() && (isFishingRod || isFishingRod1) && !(this.distanceToSqr(player) > 1024.0)) { return false; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/raid/Raid.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/raid/Raid.java.patch index 752fef308..e6400b645 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/raid/Raid.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/raid/Raid.java.patch @@ -13,11 +13,12 @@ public static final SpawnPlacementType RAVAGER_SPAWN_PLACEMENT_TYPE = SpawnPlacements.getPlacementType(EntityType.RAVAGER); public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec( instance -> instance.group( -@@ -74,6 +_,7 @@ +@@ -74,6 +_,8 @@ Raid.RaidStatus.CODEC.fieldOf("status").forGetter(raid -> raid.status), BlockPos.CODEC.fieldOf("center").forGetter(raid -> raid.center), UUIDUtil.CODEC_SET.fieldOf("heroes_of_the_village").forGetter(raid -> raid.heroesOfTheVillage) -+ , org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer.createCodec(PDC_TYPE_REGISTRY).fieldOf(PDC_NBT_KEY).forGetter(raid -> raid.persistentDataContainer) ++ , org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer.createCodec(PDC_TYPE_REGISTRY).lenientOptionalFieldOf(PDC_NBT_KEY) // Paper - add persistent data container ++ .forGetter(raid -> raid.persistentDataContainer.isEmpty() ? java.util.Optional.empty() : java.util.Optional.of(raid.persistentDataContainer)) // Paper - add persistent data container ) .apply(instance, Raid::new) ); @@ -33,7 +34,7 @@ Raid.RaidStatus status, BlockPos center, Set heroesOfTheVillage -+ , final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer // Paper - add persistent data container ++ , final Optional persistentDataContainer // Paper - add persistent data container ) { this.started = started; this.active = active; @@ -41,7 +42,7 @@ this.numGroups = numGroups; this.status = status; this.heroesOfTheVillage.addAll(heroesOfTheVillage); -+ this.persistentDataContainer = persistentDataContainer; // Paper - add persistent data container ++ this.persistentDataContainer = persistentDataContainer.orElseGet(() -> new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(PDC_TYPE_REGISTRY)); // Paper - add persistent data container } public boolean isOver() { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ContainerSynchronizer.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ContainerSynchronizer.java.patch index b5e0c30bc..23243402a 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/ContainerSynchronizer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/ContainerSynchronizer.java.patch @@ -1,15 +1,9 @@ --- a/net/minecraft/world/inventory/ContainerSynchronizer.java +++ b/net/minecraft/world/inventory/ContainerSynchronizer.java -@@ -13,4 +_,12 @@ +@@ -13,4 +_,6 @@ void sendDataChange(AbstractContainerMenu container, int id, int value); RemoteSlot createSlot(); + + default void sendOffHandSlotChange() {} // Paper - Sync offhand slot in menus -+ -+ // Paper start - add flag to simplify remote matching logic -+ default net.minecraft.server.level.@org.jspecify.annotations.Nullable ServerPlayer player() { -+ return null; -+ } -+ // Paper end - add flag to simplify remote matching logic } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/RemoteSlot.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/RemoteSlot.java.patch deleted file mode 100644 index 5002dfb42..000000000 --- a/paper-server/patches/sources/net/minecraft/world/inventory/RemoteSlot.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/net/minecraft/world/inventory/RemoteSlot.java -+++ b/net/minecraft/world/inventory/RemoteSlot.java -@@ -29,12 +_,14 @@ - - public static class Synchronized implements RemoteSlot { - private final HashedPatchMap.HashGenerator hasher; -+ private final boolean simplifyMatching; // Paper - add flag to simplify remote matching logic - @Nullable - private ItemStack remoteStack = null; - @Nullable - private HashedStack remoteHash = null; - -- public Synchronized(HashedPatchMap.HashGenerator hasher) { -+ public Synchronized(HashedPatchMap.HashGenerator hasher, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic -+ this.simplifyMatching = simplifyMatching; // Paper - add flag to simplify remote matching logic - this.hasher = hasher; - } - -@@ -54,7 +_,7 @@ - public boolean matches(ItemStack stack) { - if (this.remoteStack != null) { - return ItemStack.matches(this.remoteStack, stack); -- } else if (this.remoteHash != null && this.remoteHash.matches(stack, this.hasher)) { -+ } else if (this.remoteHash != null && this.remoteHash.matches(stack, this.hasher, this.simplifyMatching)) { // Paper - add flag to simplify remote matching logic - this.remoteStack = stack.copy(); - return true; - } else { diff --git a/paper-server/patches/sources/net/minecraft/world/item/BowItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BowItem.java.patch new file mode 100644 index 000000000..52bde9e22 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/BowItem.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/item/BowItem.java ++++ b/net/minecraft/world/item/BowItem.java +@@ -38,7 +_,7 @@ + } else { + List list = draw(stack, projectile, player); + if (level instanceof ServerLevel serverLevel && !list.isEmpty()) { +- this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, 1.0F, powerForTime == 1.0F, null); ++ this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, 1.0F, powerForTime == 1.0F, null, powerForTime); // Paper - Pass draw strength + } + + level.playSound( diff --git a/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch index ef4344e7f..b6ba21e11 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/CrossbowItem.java.patch @@ -30,6 +30,15 @@ } else { Projectile projectile = super.createProjectile(level, shooter, weapon, ammo, isCrit); if (projectile instanceof AbstractArrow abstractArrow) { +@@ -163,7 +_,7 @@ + if (level instanceof ServerLevel serverLevel) { + ChargedProjectiles chargedProjectiles = weapon.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.EMPTY); + if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) { +- this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target); ++ this.shoot(serverLevel, shooter, hand, weapon, chargedProjectiles.getItems(), velocity, inaccuracy, shooter instanceof Player, target, 1); // Paper - Pass draw strength + if (shooter instanceof ServerPlayer serverPlayer) { + CriteriaTriggers.SHOT_CROSSBOW.trigger(serverPlayer, weapon); + serverPlayer.awardStat(Stats.ITEM_USED.get(weapon.getItem())); @@ -211,7 +_,14 @@ ); } diff --git a/paper-server/patches/sources/net/minecraft/world/item/EmptyMapItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EmptyMapItem.java.patch new file mode 100644 index 000000000..9cd8c1185 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/EmptyMapItem.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/item/EmptyMapItem.java ++++ b/net/minecraft/world/item/EmptyMapItem.java +@@ -17,10 +_,16 @@ + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); + if (level instanceof ServerLevel serverLevel) { ++ org.bukkit.inventory.ItemStack emptyMap = itemInHand.asBukkitCopy(); // Paper - PlayerMapFilledEvent + itemInHand.consume(1, player); + player.awardStat(Stats.ITEM_USED.get(this)); + serverLevel.playSound(null, player, SoundEvents.UI_CARTOGRAPHY_TABLE_TAKE_RESULT, player.getSoundSource(), 1.0F, 1.0F); + ItemStack itemStack = MapItem.create(serverLevel, player.getBlockX(), player.getBlockZ(), (byte)0, true, false); ++ // Paper start - PlayerMapFilledEvent ++ io.papermc.paper.event.player.PlayerMapFilledEvent event = new io.papermc.paper.event.player.PlayerMapFilledEvent((org.bukkit.entity.Player) player.getBukkitEntity(), emptyMap, org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack)); ++ event.callEvent(); ++ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getCreatedMap()); ++ // Paper end - PlayerMapFilledEvent + if (itemInHand.isEmpty()) { + return InteractionResult.SUCCESS.heldItemTransformedTo(itemStack); + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch index 012015c26..f0a6f1e7d 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch @@ -1,5 +1,13 @@ --- a/net/minecraft/world/item/ProjectileWeaponItem.java +++ b/net/minecraft/world/item/ProjectileWeaponItem.java +@@ -50,6 +_,7 @@ + float inaccuracy, + boolean isCrit, + @Nullable LivingEntity target ++ ,float drawStrength // Paper - Pass draw strength + ) { + float f = EnchantmentHelper.processProjectileSpread(level, weapon, shooter, 0.0F); + float f1 = projectileItems.size() == 1 ? 0.0F : 2.0F * f / (projectileItems.size() - 1); @@ -62,12 +_,29 @@ float f4 = f2 + f3 * ((i + 1) / 2) * f1; f3 = -f3; @@ -14,7 +22,7 @@ + Projectile projectile = this.createProjectile(level, shooter, weapon, itemStack, isCrit); + this.shootProjectile(shooter, projectile, i1, velocity, inaccuracy, f4, target); + -+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, weapon, itemStack, projectile, hand, velocity, true); ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, weapon, itemStack, projectile, hand, drawStrength, true); + if (event.isCancelled()) { + event.getProjectile().remove(); + return; diff --git a/paper-server/patches/sources/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch index 36547c65e..9731540c3 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java.patch @@ -6,7 +6,7 @@ Vec3 vec3 = entity.position(); - if (entity.randomTeleport(d, d1, d2, true)) { + // CraftBukkit start - handle canceled status of teleport event -+ java.util.Optional status = entity.randomTeleport(d, d1, d2, true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.CHORUS_FRUIT); ++ java.util.Optional status = entity.randomTeleport(d, d1, d2, true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.CONSUMABLE_EFFECT); + + // teleport event was canceled, no more tries + if (status.isEmpty()) break; diff --git a/paper-server/patches/sources/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch b/paper-server/patches/sources/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch new file mode 100644 index 000000000..beb8db3ee --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/enchantment/EnchantmentHelper.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java ++++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java +@@ -52,8 +_,14 @@ + } + + public static ItemEnchantments updateEnchantments(ItemStack stack, Consumer updater) { ++ // Paper start - allowing updating enchantments on items without component ++ return updateEnchantments(stack, updater, false); ++ } ++ ++ public static ItemEnchantments updateEnchantments(ItemStack stack, Consumer updater, final boolean createComponentIfMissing) { ++ // Paper end - allowing updating enchantments on items without component + DataComponentType componentType = getComponentType(stack); +- ItemEnchantments itemEnchantments = stack.get(componentType); ++ ItemEnchantments itemEnchantments = createComponentIfMissing ? stack.getOrDefault(componentType, ItemEnchantments.EMPTY) : stack.get(componentType); // Paper - allowing updating enchantments on items without component + if (itemEnchantments == null) { + return ItemEnchantments.EMPTY; + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch index e037c3af1..c8c164d1a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch @@ -24,7 +24,7 @@ + // CraftBukkit start + private final CraftWorld world; + public boolean pvpMode; -+ public org.bukkit.generator.ChunkGenerator generator; ++ public @Nullable org.bukkit.generator.ChunkGenerator generator; + + public boolean captureBlockStates = false; + public boolean captureTreeGeneration = false; @@ -81,16 +81,16 @@ long biomeZoomSeed, - int maxChainedNeighborUpdates + int maxChainedNeighborUpdates, -+ org.bukkit.generator.ChunkGenerator gen, // CraftBukkit -+ org.bukkit.generator.BiomeProvider biomeProvider, // CraftBukkit -+ org.bukkit.World.Environment env, // CraftBukkit ++ @Nullable org.bukkit.generator.ChunkGenerator generator, // Paper ++ @Nullable org.bukkit.generator.BiomeProvider biomeProvider, // Paper ++ org.bukkit.World.Environment environment, // Paper + java.util.function.Function paperWorldConfigCreator // Paper - create paper world config ) { + this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot + this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config -+ this.generator = gen; -+ this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); ++ this.generator = generator; ++ this.world = new CraftWorld((ServerLevel) this, generator, biomeProvider, environment); + + for (SpawnCategory spawnCategory : SpawnCategory.values()) { + if (org.bukkit.craftbukkit.util.CraftSpawnCategory.isValidForLimits(spawnCategory)) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch index 6f3f6b65d..a71b4f55a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch @@ -1,5 +1,67 @@ --- a/net/minecraft/world/level/block/entity/BrushableBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrushableBlockEntity.java +@@ -65,9 +_,26 @@ + return false; + } else { + this.coolDownEndsAtTick = startTick + 10L; ++ // Paper start - EntityChangeBlockEvent ++ // The vanilla logic here is *so* backwards, we'd be moving basically *all* following calls down. ++ // Instead, compute vanilla ourselves up here and just replace the below usages with our computed values for a free diff-on-change. ++ final int currentCompletionStage = this.getCompletionState(); ++ final boolean enoughBrushesToBreak = ++this.brushCount >= REQUIRED_BRUSHES_TO_BREAK; ++ final int nextCompletionStage = this.getCompletionState(); ++ final boolean differentCompletionStages = currentCompletionStage != nextCompletionStage; ++ final BlockState nextBrokenBlockState = this.getBlockState().setValue(BlockStateProperties.DUSTED, nextCompletionStage); ++ if (enoughBrushesToBreak || differentCompletionStages) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent( ++ brusher, this.worldPosition, enoughBrushesToBreak ? computeTurnsTo().defaultBlockState() : nextBrokenBlockState ++ )) { ++ brushCount--; ++ return false; ++ } ++ } ++ // Paper end - EntityChangeBlockEvent + this.unpackLootTable(level, brusher, stack); +- int completionState = this.getCompletionState(); +- if (++this.brushCount >= 10) { ++ int completionState = currentCompletionStage; // Paper - EntityChangeBlockEvent - use precomputed - diff on change ++ if (enoughBrushesToBreak) { // Paper - EntityChangeBlockEvent - use precomputed - diff on change + this.brushingCompleted(level, brusher, stack); + return true; + } else { +@@ -75,7 +_,7 @@ + int completionState1 = this.getCompletionState(); + if (completionState != completionState1) { + BlockState blockState = this.getBlockState(); +- BlockState blockState1 = blockState.setValue(BlockStateProperties.DUSTED, completionState1); ++ BlockState blockState1 = nextBrokenBlockState; // Paper - EntityChangeBlockEvent - use precomputed - diff on change + level.setBlock(this.getBlockPos(), blockState1, 3); + } + +@@ -116,6 +_,11 @@ + this.dropContent(level, brusher, stack); + BlockState blockState = this.getBlockState(); + level.levelEvent(3008, this.getBlockPos(), Block.getId(blockState)); ++ // Paper start - EntityChangeEvent - extract result block logic ++ this.brushingCompleteUpdateBlock(this.computeTurnsTo()); ++ } ++ private Block computeTurnsTo() { ++ // Paper end - EntityChangeEvent - extract result block logic + Block turnsInto; + if (this.getBlockState().getBlock() instanceof BrushableBlock brushableBlock) { + turnsInto = brushableBlock.getTurnsInto(); +@@ -123,6 +_,11 @@ + turnsInto = Blocks.AIR; + } + ++ // Paper start - EntityChangeEvent - extract result block logic ++ return turnsInto; ++ } ++ public void brushingCompleteUpdateBlock(final Block turnsInto) { ++ // Paper end - EntityChangeEvent - extract result block logic + level.setBlock(this.worldPosition, turnsInto.defaultBlockState(), 3); + } + @@ -139,7 +_,12 @@ double d5 = blockPos.getZ() + 0.5 * d1 + d2; ItemEntity itemEntity = new ItemEntity(level, d3, d4, d5, this.item.split(level.random.nextInt(21) + 10)); diff --git a/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch index ab441a465..b9fffa450 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java.patch @@ -96,6 +96,20 @@ } public static void addTargetDecoration(ItemStack stack, BlockPos pos, String type, Holder mapDecorationType) { +@@ -354,7 +_,12 @@ + } + + public void setColorsDirty(int x, int z) { +- this.setDirty(); ++ // Paper start - Fix unnecessary map data saves ++ this.setColorsDirty(x, z, true); ++ } ++ public void setColorsDirty(int x, int z, boolean markFileDirty) { ++ if (markFileDirty) this.setDirty(); ++ // Paper end - Fix unnecessary map data saves + + for (MapItemSavedData.HoldingPlayer holdingPlayer : this.carriedBy) { + holdingPlayer.markColorsDirty(x, z); @@ -395,7 +_,7 @@ return true; } diff --git a/paper-server/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/paper-server/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java index bad941054..d0554ed66 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java @@ -43,7 +43,7 @@ public class PaperVersionFetcher implements VersionFetcher { } @Override - public Component getVersionMessage(final String serverVersion) { + public Component getVersionMessage() { final Component updateMessage; final ServerBuildInfo build = ServerBuildInfo.buildInfo(); if (build.buildNumber().isEmpty() && build.gitCommit().isEmpty()) { diff --git a/paper-server/src/main/java/io/papermc/paper/PaperServerInternalAPIBridge.java b/paper-server/src/main/java/io/papermc/paper/PaperServerInternalAPIBridge.java index 43e88cd77..d69335626 100644 --- a/paper-server/src/main/java/io/papermc/paper/PaperServerInternalAPIBridge.java +++ b/paper-server/src/main/java/io/papermc/paper/PaperServerInternalAPIBridge.java @@ -1,10 +1,21 @@ package io.papermc.paper; +import io.papermc.paper.world.damagesource.CombatEntry; +import io.papermc.paper.world.damagesource.FallLocationType; +import io.papermc.paper.world.damagesource.PaperCombatEntryWrapper; +import io.papermc.paper.world.damagesource.PaperCombatTrackerWrapper; +import net.minecraft.Optionull; +import net.minecraft.world.damagesource.FallLocation; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.damage.CraftDamageEffect; +import org.bukkit.craftbukkit.damage.CraftDamageSource; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.damage.DamageEffect; +import org.bukkit.damage.DamageSource; +import org.bukkit.entity.LivingEntity; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; @NullMarked public class PaperServerInternalAPIBridge implements InternalAPIBridge { @@ -22,4 +33,42 @@ public class PaperServerInternalAPIBridge implements InternalAPIBridge { } return Holder.LEGACY_CUSTOM; } + + @Override + public CombatEntry createCombatEntry(final LivingEntity entity, final DamageSource damageSource, final float damage) { + final net.minecraft.world.entity.LivingEntity mob = ((CraftLivingEntity) entity).getHandle(); + final FallLocation fallLocation = FallLocation.getCurrentFallLocation(mob); + return createCombatEntry( + ((CraftDamageSource) damageSource).getHandle(), + damage, + fallLocation, + (float) mob.fallDistance + ); + } + + @Override + public CombatEntry createCombatEntry( + final DamageSource damageSource, + final float damage, + @Nullable final FallLocationType fallLocationType, + final float fallDistance + ) { + return createCombatEntry( + ((CraftDamageSource) damageSource).getHandle(), + damage, + Optionull.map(fallLocationType, PaperCombatTrackerWrapper::paperToMinecraft), + fallDistance + ); + } + + private CombatEntry createCombatEntry( + final net.minecraft.world.damagesource.DamageSource damageSource, + final float damage, + final net.minecraft.world.damagesource.@Nullable FallLocation fallLocation, + final float fallDistance + ) { + return new PaperCombatEntryWrapper(new net.minecraft.world.damagesource.CombatEntry( + damageSource, damage, fallLocation, fallDistance + )); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/command/PaperCommand.java b/paper-server/src/main/java/io/papermc/paper/command/PaperCommand.java index 8d0471153..33b10d4eb 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/PaperCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/PaperCommand.java @@ -1,7 +1,15 @@ package io.papermc.paper.command; import io.papermc.paper.FeatureHooks; -import io.papermc.paper.command.subcommands.*; +import io.papermc.paper.command.subcommands.DumpItemCommand; +import io.papermc.paper.command.subcommands.DumpListenersCommand; +import io.papermc.paper.command.subcommands.DumpPluginsCommand; +import io.papermc.paper.command.subcommands.EntityCommand; +import io.papermc.paper.command.subcommands.HeapDumpCommand; +import io.papermc.paper.command.subcommands.MobcapsCommand; +import io.papermc.paper.command.subcommands.ReloadCommand; +import io.papermc.paper.command.subcommands.SyncLoadInfoCommand; +import io.papermc.paper.command.subcommands.VersionCommand; import it.unimi.dsi.fastutil.Pair; import java.util.ArrayList; import java.util.Arrays; diff --git a/paper-server/src/main/java/io/papermc/paper/command/PaperCommands.java b/paper-server/src/main/java/io/papermc/paper/command/PaperCommands.java index 7b58b2d62..f3f466ee5 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/PaperCommands.java +++ b/paper-server/src/main/java/io/papermc/paper/command/PaperCommands.java @@ -1,10 +1,15 @@ package io.papermc.paper.command; +import com.mojang.brigadier.tree.LiteralCommandNode; +import io.papermc.paper.command.brigadier.CommandRegistrationFlag; +import io.papermc.paper.command.brigadier.CommandSourceStack; import net.minecraft.server.MinecraftServer; import org.bukkit.command.Command; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Set; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; @@ -15,16 +20,32 @@ public final class PaperCommands { } private static final Map COMMANDS = new HashMap<>(); - static { + + public static void registerCommands(final MinecraftServer server) { COMMANDS.put("paper", new PaperCommand("paper")); COMMANDS.put("callback", new CallbackCommand("callback")); COMMANDS.put("mspt", new MSPTCommand("mspt")); - } - public static void registerCommands(final MinecraftServer server) { COMMANDS.forEach((s, command) -> { server.server.getCommandMap().register(s, "Paper", command); }); server.server.getCommandMap().register("bukkit", new PaperPluginsCommand()); } + + public static void registerCommands() { + // Paper commands go here + registerInternalCommand(PaperVersionCommand.create(), "bukkit", PaperVersionCommand.DESCRIPTION, List.of("ver", "about"), Set.of()); + } + + private static void registerInternalCommand(final LiteralCommandNode node, final String namespace, final String description, final List aliases, final Set flags) { + io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.registerWithFlagsInternal( + null, + namespace, + "Paper", + node, + description, + aliases, + flags + ); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/command/PaperVersionCommand.java b/paper-server/src/main/java/io/papermc/paper/command/PaperVersionCommand.java new file mode 100644 index 000000000..a7d1a959a --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/command/PaperVersionCommand.java @@ -0,0 +1,184 @@ +package io.papermc.paper.command; + +import com.destroystokyo.paper.PaperVersionFetcher; +import com.destroystokyo.paper.util.VersionFetcher; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import com.mojang.brigadier.tree.LiteralCommandNode; +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.command.brigadier.Commands; +import io.papermc.paper.plugin.configuration.PluginMeta; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.JoinConfiguration; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.event.ClickEvent; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.StringUtil; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class PaperVersionCommand { + public static final String DESCRIPTION = "Gets the version of this server including any plugins in use"; + + private static final Component NOT_RUNNING = Component.text() + .append(Component.text("This server is not running any plugin by that name.")) + .appendNewline() + .append(Component.text("Use /plugins to get a list of plugins.").clickEvent(ClickEvent.suggestCommand("/plugins"))) + .build(); + private static final JoinConfiguration PLAYER_JOIN_CONFIGURATION = JoinConfiguration.separators( + Component.text(", ", NamedTextColor.WHITE), + Component.text(", and ", NamedTextColor.WHITE) + ); + private static final Component FAILED_TO_FETCH = Component.text("Could not fetch version information!", NamedTextColor.RED); + private static final Component FETCHING = Component.text("Checking version, please wait...", NamedTextColor.WHITE, TextDecoration.ITALIC); + + private final VersionFetcher versionFetcher = new PaperVersionFetcher(); + private CompletableFuture computedVersion = CompletableFuture.completedFuture(new ComputedVersion(Component.empty(), -1)); // Precompute-- someday move that stuff out of bukkit + + public static LiteralCommandNode create() { + final PaperVersionCommand command = new PaperVersionCommand(); + + return Commands.literal("version") + .requires(source -> source.getSender().hasPermission("bukkit.command.version")) + .then(Commands.argument("plugin", StringArgumentType.word()) + .suggests(command::suggestPlugins) + .executes(command::pluginVersion)) + .executes(command::serverVersion) + .build(); + } + + private int pluginVersion(final CommandContext context) { + final CommandSender sender = context.getSource().getSender(); + final String pluginName = context.getArgument("plugin", String.class).toLowerCase(Locale.ROOT); + + Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName); + if (plugin == null) { + plugin = Arrays.stream(Bukkit.getPluginManager().getPlugins()) + .filter(checkPlugin -> checkPlugin.getName().toLowerCase(Locale.ROOT).contains(pluginName)) + .findAny() + .orElse(null); + } + + if (plugin != null) { + this.sendPluginInfo(plugin, sender); + } else { + sender.sendMessage(NOT_RUNNING); + } + + return Command.SINGLE_SUCCESS; + } + + private CompletableFuture suggestPlugins(final CommandContext context, final SuggestionsBuilder builder) { + for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + final String name = plugin.getName(); + if (StringUtil.startsWithIgnoreCase(name, builder.getRemainingLowerCase())) { + builder.suggest(name); + } + } + + return CompletableFuture.completedFuture(builder.build()); + } + + private void sendPluginInfo(final Plugin plugin, final CommandSender sender) { + final PluginMeta meta = plugin.getPluginMeta(); + + final TextComponent.Builder builder = Component.text() + .append(Component.text(meta.getName())) + .append(Component.text(" version ")) + .append(Component.text(meta.getVersion(), NamedTextColor.GREEN) + .hoverEvent(Component.translatable("chat.copy.click")) + .clickEvent(ClickEvent.copyToClipboard(meta.getVersion())) + ); + + if (meta.getDescription() != null) { + builder + .appendNewline() + .append(Component.text(meta.getDescription())); + } + + if (meta.getWebsite() != null) { + Component websiteComponent = Component.text(meta.getWebsite(), NamedTextColor.GREEN).clickEvent(ClickEvent.openUrl(meta.getWebsite())); + builder.appendNewline().append(Component.text("Website: ").append(websiteComponent)); + } + + if (!meta.getAuthors().isEmpty()) { + String prefix = meta.getAuthors().size() == 1 ? "Author: " : "Authors: "; + builder.appendNewline().append(Component.text(prefix).append(formatNameList(meta.getAuthors()))); + } + + if (!meta.getContributors().isEmpty()) { + builder.appendNewline().append(Component.text("Contributors: ").append(formatNameList(meta.getContributors()))); + } + sender.sendMessage(builder.build()); + } + + private static Component formatNameList(final List names) { + return Component.join(PLAYER_JOIN_CONFIGURATION, names.stream().map(Component::text).toList()).color(NamedTextColor.GREEN); + } + + private int serverVersion(CommandContext context) { + sendVersion(context.getSource().getSender()); + return Command.SINGLE_SUCCESS; + } + + private void sendVersion(final CommandSender sender) { + final CompletableFuture version = getVersionOrFetch(); + if (!version.isDone()) { + sender.sendMessage(FETCHING); + } + + version.whenComplete((computedVersion, throwable) -> { + if (computedVersion != null) { + sender.sendMessage(computedVersion.message); + } else if (throwable != null) { + sender.sendMessage(FAILED_TO_FETCH); + MinecraftServer.LOGGER.warn("Could not fetch version information!", throwable); + } + }); + } + + private CompletableFuture getVersionOrFetch() { + if (!this.computedVersion.isDone()) { + return this.computedVersion; + } + + if (this.computedVersion.isCompletedExceptionally() || System.currentTimeMillis() - this.computedVersion.resultNow().computedTime() > this.versionFetcher.getCacheTime()) { + this.computedVersion = this.fetchVersionMessage(); + } + + return this.computedVersion; + } + + private CompletableFuture fetchVersionMessage() { + return CompletableFuture.supplyAsync(() -> { + final Component message = Component.textOfChildren( + Component.text(Bukkit.getVersionMessage(), NamedTextColor.WHITE), + Component.newline(), + this.versionFetcher.getVersionMessage() + ); + + return new ComputedVersion( + message.hoverEvent(Component.translatable("chat.copy.click", NamedTextColor.WHITE)) + .clickEvent(ClickEvent.copyToClipboard(PlainTextComponentSerializer.plainText().serialize(message))), + System.currentTimeMillis() + ); + }); + } + + record ComputedVersion(Component message, long computedTime) { + + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java new file mode 100644 index 000000000..90a604cfc --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java @@ -0,0 +1,31 @@ +package io.papermc.paper.command.brigadier; + +import io.papermc.paper.plugin.configuration.PluginMeta; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@NullMarked +public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List aliases, @Nullable String helpCommandNamespace, boolean serverSideOnly) { + + public APICommandMeta(final @Nullable PluginMeta pluginMeta, final @Nullable String description) { + this(pluginMeta, description, Collections.emptyList(), null, false); + } + + public APICommandMeta { + aliases = List.copyOf(aliases); + } + + @Nullable + public Plugin plugin() { + return this.pluginMeta == null ? null : Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.pluginMeta.getName())); + } + + public APICommandMeta withAliases(List registeredAliases) { + return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace, this.serverSideOnly); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java index 944cd8328..2d1de331a 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperBrigadier.java @@ -35,8 +35,8 @@ public final class PaperBrigadier { throw new IllegalArgumentException("Unsure how to wrap a " + node); } - final PluginCommandMeta meta; - if ((meta = node.pluginCommandMeta) == null) { + final APICommandMeta meta; + if ((meta = node.apiCommandMeta) == null) { return new VanillaCommandWrapper(node); } CommandNode argumentCommandNode = node; @@ -46,6 +46,12 @@ public final class PaperBrigadier { Map, String> map = PaperCommands.INSTANCE.getDispatcherInternal().getSmartUsage(argumentCommandNode, DUMMY); String usage = map.isEmpty() ? node.getUsageText() : node.getUsageText() + " " + String.join("\n" + node.getUsageText() + " ", map.values()); + + // Internal command + if (meta.pluginMeta() == null) { + return new VanillaCommandWrapper(node.getName(), meta.description(), usage, meta.aliases(), node, meta.helpCommandNamespace()); + } + return new PluginVanillaCommandWrapper(node.getName(), meta.description(), usage, meta.aliases(), node, meta.plugin()); } diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java index 4b6d84542..84fab94f3 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java @@ -91,10 +91,13 @@ public class PaperCommands implements Commands, PaperRegistrar registerWithFlags(final PluginMeta pluginMeta, final LiteralCommandNode node, final @Nullable String description, final Collection aliases, final Set flags) { - final PluginCommandMeta meta = new PluginCommandMeta(pluginMeta, description); - final String identifier = pluginMeta.getName().toLowerCase(Locale.ROOT); + return registerWithFlagsInternal(pluginMeta, pluginMeta.getName().toLowerCase(Locale.ROOT), null, node, description, aliases, flags); + } + + public @Unmodifiable Set registerWithFlagsInternal(final @Nullable PluginMeta pluginMeta, final String namespace, final @Nullable String helpNamespaceOverride, final LiteralCommandNode node, final @Nullable String description, final Collection aliases, final Set flags) { + final APICommandMeta meta = new APICommandMeta(pluginMeta, description, List.of(), helpNamespaceOverride, flags.contains(CommandRegistrationFlag.SERVER_ONLY)); final String literal = node.getLiteral(); - final LiteralCommandNode pluginLiteral = PaperBrigadier.copyLiteral(identifier + ":" + literal, node); + final LiteralCommandNode pluginLiteral = PaperBrigadier.copyLiteral(namespace + ":" + literal, node); final Set registeredLabels = new HashSet<>(aliases.size() * 2 + 2); @@ -111,27 +114,27 @@ public class PaperCommands implements Commands, PaperRegistrar redirectTo, final PluginCommandMeta meta) { + private boolean registerCopy(final String aliasLiteral, final LiteralCommandNode redirectTo, final APICommandMeta meta) { final LiteralCommandNode node = PaperBrigadier.copyLiteral(aliasLiteral, redirectTo); - node.pluginCommandMeta = meta; + node.apiCommandMeta = meta; return this.registerIntoDispatcher(node, false); } private boolean registerIntoDispatcher(final LiteralCommandNode node, boolean override) { final CommandNode existingChild = this.getDispatcher().getRoot().getChild(node.getLiteral()); - if (existingChild != null && existingChild.pluginCommandMeta == null && !(existingChild instanceof BukkitCommandNode)) { + if (existingChild != null && existingChild.apiCommandMeta == null && !(existingChild instanceof BukkitCommandNode)) { override = true; // override vanilla commands } if (existingChild == null || override) { // Avoid merging behavior. Maybe something to look into in the future diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandMeta.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandMeta.java deleted file mode 100644 index 45701bcca..000000000 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandMeta.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.papermc.paper.command.brigadier; - -import io.papermc.paper.plugin.configuration.PluginMeta; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.jspecify.annotations.NullMarked; -import org.jspecify.annotations.Nullable; - -@NullMarked -public record PluginCommandMeta(PluginMeta pluginMeta, @Nullable String description, List aliases) { - - public PluginCommandMeta(final PluginMeta pluginMeta, final @Nullable String description) { - this(pluginMeta, description, Collections.emptyList()); - } - - public PluginCommandMeta { - aliases = List.copyOf(aliases); - } - - public Plugin plugin() { - return Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.pluginMeta.getName())); - } -} diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginVanillaCommandWrapper.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginVanillaCommandWrapper.java index a0e2ac509..a9b6d2781 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginVanillaCommandWrapper.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginVanillaCommandWrapper.java @@ -17,7 +17,7 @@ public class PluginVanillaCommandWrapper extends VanillaCommandWrapper implement private final List aliases; public PluginVanillaCommandWrapper(String name, String description, String usageMessage, List aliases, CommandNode vanillaCommand, Plugin plugin) { - super(name, description, usageMessage, aliases, vanillaCommand); + super(name, description, usageMessage, aliases, vanillaCommand, null); this.plugin = plugin; this.aliases = aliases; } diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProviderImpl.java index b41d4a1fc..4aa656df2 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProviderImpl.java @@ -86,6 +86,7 @@ import org.bukkit.block.structure.Mirror; import org.bukkit.block.structure.StructureRotation; import org.bukkit.craftbukkit.CraftHeightMap; import org.bukkit.craftbukkit.CraftRegistry; +import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBlockStates; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.scoreboard.CraftCriteria; @@ -172,7 +173,11 @@ public class VanillaArgumentProviderImpl implements VanillaArgumentProvider { @Override public ArgumentType blockState() { return this.wrap(BlockStateArgument.block(PaperCommands.INSTANCE.getBuildContext()), (result) -> { - return CraftBlockStates.getBlockState(CraftRegistry.getMinecraftRegistry(), BlockPos.ZERO, result.getState(), result.tag); + final BlockState snapshot = CraftBlockStates.getBlockState(CraftRegistry.getMinecraftRegistry(), BlockPos.ZERO, result.getState(), null); + if (result.tag != null && snapshot instanceof final CraftBlockEntityState blockEntitySnapshot) { + blockEntitySnapshot.loadData(result.tag); + } + return snapshot; }); } diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java index 5eef7ae51..4ee648f96 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitBrigForwardingMap.java @@ -47,7 +47,7 @@ public class BukkitBrigForwardingMap extends HashMap { @Override public boolean isEmpty() { - return this.size() != 0; + return this.size() == 0; } @Override diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java index 1814cd072..5c52b1563 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java @@ -10,9 +10,10 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.tree.LiteralCommandNode; import io.papermc.paper.command.brigadier.CommandSourceStack; import java.util.ArrayList; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.commands.CommandSource; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.command.Command; import org.bukkit.command.CommandException; @@ -107,7 +108,7 @@ public class BukkitCommandNode extends LiteralCommandNode { try { results = this.command.tabComplete(sender, this.literal, args, pos.clone()); } catch (CommandException ex) { - sender.sendMessage(ChatColor.RED + "An internal error occurred while attempting to tab-complete this command"); + sender.sendMessage(Component.text("An internal error occurred while attempting to tab-complete this command", NamedTextColor.RED)); Bukkit.getServer().getLogger().log(Level.SEVERE, "Exception when " + sender.getName() + " attempted to tab complete " + builder.getRemaining(), ex); } diff --git a/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java b/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java index aa44d4685..9c79d8757 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpListenersCommand.java @@ -2,12 +2,13 @@ package io.papermc.paper.command.subcommands; import com.destroystokyo.paper.util.SneakyThrow; import io.papermc.paper.command.PaperSubcommand; -import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.Path; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -16,6 +17,7 @@ import java.util.List; import java.util.Locale; import java.util.Set; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.event.ClickEvent; import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @@ -23,6 +25,7 @@ import org.bukkit.event.HandlerList; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredListener; import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; import static net.kyori.adventure.text.Component.newline; @@ -35,6 +38,8 @@ import static net.kyori.adventure.text.format.NamedTextColor.WHITE; @DefaultQualifier(NonNull.class) public final class DumpListenersCommand implements PaperSubcommand { + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss"); + private static final String COMMAND_ARGUMENT_TO_FILE = "tofile"; private static final MethodHandle EVENT_TYPES_HANDLE; static { @@ -49,7 +54,7 @@ public final class DumpListenersCommand implements PaperSubcommand { @Override public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { - if (args.length >= 1 && args[0].equals("tofile")) { + if (args.length >= 1 && args[0].equals(COMMAND_ARGUMENT_TO_FILE)) { this.dumpToFile(sender); return true; } @@ -58,45 +63,69 @@ public final class DumpListenersCommand implements PaperSubcommand { } private void dumpToFile(final CommandSender sender) { - final File file = new File("debug/listeners-" - + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt"); - file.getParentFile().mkdirs(); - try (final PrintWriter writer = new PrintWriter(file)) { - for (final String eventClass : eventClassNames()) { - final HandlerList handlers; - try { - handlers = (HandlerList) findClass(eventClass).getMethod("getHandlerList").invoke(null); - } catch (final ReflectiveOperationException e) { - continue; - } - if (handlers.getRegisteredListeners().length != 0) { - writer.println(eventClass); - } - for (final RegisteredListener registeredListener : handlers.getRegisteredListeners()) { - writer.println(" - " + registeredListener); + Path parent = Path.of("debug"); + Path path = parent.resolve("listeners-" + FORMATTER.format(LocalDateTime.now()) + ".txt"); + sender.sendMessage( + text("Writing listeners into directory", GREEN) + .appendSpace() + .append( + text(parent.toString(), WHITE) + .hoverEvent(text("Click to copy the full path of debug directory", WHITE)) + .clickEvent(ClickEvent.copyToClipboard(parent.toAbsolutePath().toString())) + ) + ); + try { + Files.createDirectories(parent); + Files.createFile(path); + try (final PrintWriter writer = new PrintWriter(path.toFile())){ + for (final String eventClass : eventClassNames()) { + final HandlerList handlers; + try { + handlers = (HandlerList) findClass(eventClass).getMethod("getHandlerList").invoke(null); + } catch (final ReflectiveOperationException e) { + continue; + } + if (handlers.getRegisteredListeners().length != 0) { + writer.println(eventClass); + } + for (final RegisteredListener registeredListener : handlers.getRegisteredListeners()) { + writer.println(" - " + registeredListener); + } } } } catch (final IOException ex) { - throw new RuntimeException(ex); + sender.sendMessage(text("Failed to write dumped listener! See the console for more info.", RED)); + MinecraftServer.LOGGER.warn("Error occurred while dumping listeners", ex); + return; } - sender.sendMessage(text("Dumped listeners to " + file, GREEN)); + sender.sendMessage( + text("Successfully written listeners into", GREEN) + .appendSpace() + .append( + text(path.toString(), WHITE) + .hoverEvent(text("Click to copy the full path of the file", WHITE)) + .clickEvent(ClickEvent.copyToClipboard(path.toAbsolutePath().toString())) + ) + ); } private void doDumpListeners(final CommandSender sender, final String[] args) { if (args.length == 0) { - sender.sendMessage(text("Usage: /paper dumplisteners tofile|", RED)); + sender.sendMessage(text("Usage: /paper dumplisteners " + COMMAND_ARGUMENT_TO_FILE + "|", RED)); return; } + final String className = args[0]; + try { - final HandlerList handlers = (HandlerList) findClass(args[0]).getMethod("getHandlerList").invoke(null); + final HandlerList handlers = (HandlerList) findClass(className).getMethod("getHandlerList").invoke(null); if (handlers.getRegisteredListeners().length == 0) { - sender.sendMessage(text(args[0] + " does not have any registered listeners.")); + sender.sendMessage(text(className + " does not have any registered listeners.")); return; } - sender.sendMessage(text("Listeners for " + args[0] + ":")); + sender.sendMessage(text("Listeners for " + className + ":")); for (final RegisteredListener listener : handlers.getRegisteredListeners()) { final Component hoverText = text("Priority: " + listener.getPriority().name() + " (" + listener.getPriority().getSlot() + ")", WHITE) @@ -115,12 +144,12 @@ public final class DumpListenersCommand implements PaperSubcommand { sender.sendMessage(text("Total listeners: " + handlers.getRegisteredListeners().length)); } catch (final ClassNotFoundException e) { - sender.sendMessage(text("Unable to find a class named '" + args[0] + "'. Make sure to use the fully qualified name.", RED)); + sender.sendMessage(text("Unable to find a class named '" + className + "'. Make sure to use the fully qualified name.", RED)); } catch (final NoSuchMethodException e) { - sender.sendMessage(text("Class '" + args[0] + "' does not have a valid getHandlerList method.", RED)); + sender.sendMessage(text("Class '" + className + "' does not have a valid getHandlerList method.", RED)); } catch (final ReflectiveOperationException e) { sender.sendMessage(text("Something went wrong, see the console for more details.", RED)); - MinecraftServer.LOGGER.warn("Error occurred while dumping listeners for class " + args[0], e); + MinecraftServer.LOGGER.warn("Error occurred while dumping listeners for class {}", className, e); } } @@ -137,7 +166,7 @@ public final class DumpListenersCommand implements PaperSubcommand { private static List suggestions() { final List ret = new ArrayList<>(); - ret.add("tofile"); + ret.add(COMMAND_ARGUMENT_TO_FILE); ret.addAll(eventClassNames()); return ret; } diff --git a/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java b/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java index d4a092243..0f8983d07 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java @@ -5,6 +5,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; +import com.google.gson.Strictness; import com.google.gson.internal.Streams; import com.google.gson.stream.JsonWriter; import io.papermc.paper.command.PaperSubcommand; @@ -15,7 +16,6 @@ import io.papermc.paper.plugin.entrypoint.classloader.group.PaperPluginClassLoad import io.papermc.paper.plugin.entrypoint.classloader.group.SimpleListPluginClassLoaderGroup; import io.papermc.paper.plugin.entrypoint.classloader.group.SpigotPluginClassLoaderGroup; import io.papermc.paper.plugin.entrypoint.classloader.group.StaticPluginClassLoaderGroup; -import io.papermc.paper.plugin.entrypoint.dependency.GraphDependencyContext; import io.papermc.paper.plugin.entrypoint.dependency.SimpleMetaDependencyTree; import io.papermc.paper.plugin.provider.entrypoint.DependencyContext; import io.papermc.paper.plugin.entrypoint.strategy.modern.ModernPluginLoadingStrategy; @@ -27,12 +27,14 @@ import io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage; import io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup; import io.papermc.paper.plugin.storage.ConfiguredProviderStorage; import io.papermc.paper.plugin.storage.ProviderStorage; +import net.kyori.adventure.text.event.ClickEvent; import net.minecraft.server.MinecraftServer; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.framework.qual.DefaultQualifier; +import java.io.IOException; import java.io.PrintStream; import java.io.StringWriter; import java.nio.charset.StandardCharsets; @@ -47,6 +49,7 @@ import java.util.Map; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; import static net.kyori.adventure.text.format.NamedTextColor.RED; +import static net.kyori.adventure.text.format.NamedTextColor.WHITE; @DefaultQualifier(NonNull.class) public final class DumpPluginsCommand implements PaperSubcommand { @@ -60,24 +63,40 @@ public final class DumpPluginsCommand implements PaperSubcommand { private void dumpPlugins(final CommandSender sender, final String[] args) { Path parent = Path.of("debug"); - Path path = parent.resolve("plugin-info-" + FORMATTER.format(LocalDateTime.now()) + ".txt"); + Path path = parent.resolve("plugin-info-" + FORMATTER.format(LocalDateTime.now()) + ".json"); try { Files.createDirectories(parent); Files.createFile(path); - sender.sendMessage(text("Writing plugin information to " + path, GREEN)); + sender.sendMessage( + text("Writing plugin information into directory", GREEN) + .appendSpace() + .append( + text(parent.toString(), WHITE) + .hoverEvent(text("Click to copy the full path of debug directory", WHITE)) + .clickEvent(ClickEvent.copyToClipboard(parent.toAbsolutePath().toString())) + ) + ); final JsonObject data = this.writeDebug(); StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter); jsonWriter.setIndent(" "); - jsonWriter.setLenient(false); + jsonWriter.setStrictness(Strictness.STRICT); Streams.write(data, jsonWriter); try (PrintStream out = new PrintStream(Files.newOutputStream(path), false, StandardCharsets.UTF_8)) { out.print(stringWriter); } - sender.sendMessage(text("Successfully written plugin debug information!", GREEN)); + sender.sendMessage( + text("Successfully written plugin debug information into", GREEN) + .appendSpace() + .append( + text(path.toString(), WHITE) + .hoverEvent(text("Click to copy the full path of the file", WHITE)) + .clickEvent(ClickEvent.copyToClipboard(path.toAbsolutePath().toString())) + ) + ); } catch (Throwable e) { sender.sendMessage(text("Failed to write plugin information! See the console for more info.", RED)); MinecraftServer.LOGGER.warn("Error occurred while dumping plugin info", e); @@ -97,6 +116,7 @@ public final class DumpPluginsCommand implements PaperSubcommand { return root; } + @SuppressWarnings("unchecked") private void writeProviders(JsonObject root) { JsonObject rootProviders = new JsonObject(); root.add("providers", rootProviders); @@ -116,7 +136,6 @@ public final class DumpPluginsCommand implements PaperSubcommand { providerObj.addProperty("soft-dependencies", provider.getMeta().getPluginSoftDependencies().toString()); providerObj.addProperty("load-before", provider.getMeta().getLoadBeforePlugins().toString()); - providers.add(providerObj); pluginProviders.add((PluginProvider) provider); } diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java b/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java index f34c649a1..5110e8836 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/Configurations.java @@ -62,7 +62,8 @@ public abstract class Configurations { protected ObjectMapper.Factory.Builder createObjectMapper() { return ObjectMapper.factoryBuilder() .addConstraint(Constraint.class, new Constraint.Factory()) - .addConstraint(Constraints.Min.class, Number.class, new Constraints.Min.Factory()); + .addConstraint(Constraints.Min.class, Number.class, new Constraints.Min.Factory()) + .addConstraint(Constraints.Max.class, Number.class, new Constraints.Max.Factory()); } protected YamlConfigurationLoader.Builder createLoaderBuilder() { diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java index 6e9bfd986..c2b53adb5 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -185,8 +185,6 @@ public class GlobalConfiguration extends ConfigurationPart { public CompressionFormat compressionFormat = CompressionFormat.ZLIB; @Comment("This setting controls if equipment should be updated when handling certain player actions.") public boolean updateEquipmentOnPlayerActions = true; - @Comment("Only checks an item's amount and type instead of its full data during inventory desync checks.") - public boolean simplifyRemoteItemMatching = false; public enum CompressionFormat { GZIP, @@ -356,6 +354,9 @@ public class GlobalConfiguration extends ConfigurationPart { public IntOr.Default compressionLevel = IntOr.Default.USE_DEFAULT; @Comment("Defines the leniency distance added on the server to the interaction range of a player when validating interact packets.") public DoubleOr.Default clientInteractionLeniencyDistance = DoubleOr.Default.USE_DEFAULT; + @Comment("Defines how many orbs groups can exist in an area.") + @Constraints.Min(1) + public IntOr.Default xpOrbGroupsPerArea = IntOr.Default.USE_DEFAULT; } public BlockUpdates blockUpdates; diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/PaperServerConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/PaperServerConfiguration.java new file mode 100644 index 000000000..14d0965f4 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/configuration/PaperServerConfiguration.java @@ -0,0 +1,9 @@ +package io.papermc.paper.configuration; + +public class PaperServerConfiguration implements ServerConfiguration { + + @Override + public boolean isProxyOnlineMode() { + return GlobalConfiguration.get().proxies.isProxyOnlineMode(); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java b/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java index 9cab83a5b..0353ed62e 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java @@ -40,4 +40,22 @@ public final class Constraints { } } } + + @Documented + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Max { + int value(); + + final class Factory implements Constraint.Factory { + @Override + public Constraint make(Max data, Type type) { + return value -> { + if (value != null && value.intValue() > data.value()) { + throw new SerializationException(value + " is greater than the max " + data.value()); + } + }; + } + } + } } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java index 1748518bb..b4b9df9d8 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java @@ -2,8 +2,13 @@ package io.papermc.paper.datacomponent.item; import com.google.common.base.Preconditions; import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.datacomponent.item.blocksattacks.DamageReduction; +import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction; +import io.papermc.paper.datacomponent.item.blocksattacks.PaperDamageReduction; +import io.papermc.paper.datacomponent.item.blocksattacks.PaperItemDamageFunction; import io.papermc.paper.registry.PaperRegistries; import io.papermc.paper.registry.tag.TagKey; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import net.kyori.adventure.key.Key; @@ -30,6 +35,16 @@ public record PaperBlocksAttacks( return this.impl.disableCooldownScale(); } + @Override + public List damageReductions() { + return this.impl.damageReductions().stream().map(PaperDamageReduction::new).map(paperDamageReduction -> ((DamageReduction) paperDamageReduction)).toList(); + } + + @Override + public ItemDamageFunction itemDamage() { + return new PaperItemDamageFunction(this.impl.itemDamage()); + } + @Override public @Nullable TagKey bypassedBy() { final Optional> tagKey = this.impl.bypassedBy().map(PaperRegistries::fromNms); @@ -50,8 +65,8 @@ public record PaperBlocksAttacks( private float blockDelaySeconds; private float disableCooldownScale = 1.0F; - //private List damageReductions = List.of(); - //private ItemDamageFunction itemDamage = ItemDamageFunction.DEFAULT; + private List damageReductions = new ArrayList<>(); + private ItemDamageFunction itemDamage = new PaperItemDamageFunction(net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT); private @Nullable TagKey bypassedBy; private @Nullable Key blockSound; private @Nullable Key disableSound; @@ -70,15 +85,18 @@ public record PaperBlocksAttacks( return this; } - //@Override - //public Builder addDamageReduction(final DamageReduction reduction) { - // return null; - //} + @Override + public Builder addDamageReduction(final DamageReduction reduction) { + Preconditions.checkArgument(reduction.horizontalBlockingAngle() >= 0, "horizontalBlockingAngle must be non-negative, was %s", reduction.horizontalBlockingAngle()); + this.damageReductions.add(reduction); + return this; + } - //@Override - //public Builder itemDamage(final ItemDamageFunction function) { - // return null; - //} + @Override + public Builder itemDamage(final ItemDamageFunction function) { + this.itemDamage = function; + return this; + } @Override public Builder bypassedBy(@Nullable final TagKey bypassedBy) { @@ -98,18 +116,19 @@ public record PaperBlocksAttacks( return this; } - //@Override - //public Builder damageReductions(final List reductions) { - // return null; - //} + @Override + public Builder damageReductions(final List reductions) { + this.damageReductions = new ArrayList<>(reductions); + return this; + } @Override public BlocksAttacks build() { return new PaperBlocksAttacks(new net.minecraft.world.item.component.BlocksAttacks( this.blockDelaySeconds, this.disableCooldownScale, - List.of(), // TODO - net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT, // TODO + this.damageReductions.stream().map(damageReduction -> ((PaperDamageReduction) damageReduction).getHandle()).toList(), + ((PaperItemDamageFunction) itemDamage).getHandle(), Optional.ofNullable(this.bypassedBy).map(PaperRegistries::toNms), Optional.ofNullable(this.blockSound).map(PaperAdventure::resolveSound), Optional.ofNullable(this.disableSound).map(PaperAdventure::resolveSound) diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java index 4712f8bba..d1ddcc17d 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java @@ -5,6 +5,8 @@ import io.papermc.paper.util.MCUtil; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; import net.minecraft.world.effect.MobEffectInstance; import org.bukkit.Color; import org.bukkit.craftbukkit.potion.CraftPotionType; @@ -48,6 +50,19 @@ public record PaperPotionContents( return this.impl.customName().orElse(null); } + @Override + public @Unmodifiable List allEffects() { + //noinspection SimplifyStreamApiCallChains - explicity want it unmodifiable, as toList() api doesnt guarantee this. + return StreamSupport.stream(this.impl.getAllEffects().spliterator(), false) + .map(CraftPotionUtil::toBukkit) + .collect(Collectors.toUnmodifiableList()); + } + + @Override + public Color computeEffectiveColor() { + return Color.fromARGB(this.impl.getColor()); + } + static final class BuilderImpl implements PotionContents.Builder { private final List customEffects = new ObjectArrayList<>(); diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java new file mode 100644 index 000000000..865563be3 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java @@ -0,0 +1,19 @@ +package io.papermc.paper.datacomponent.item.blocksattacks; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +@ApiStatus.Internal +@NullMarked +public class BlocksAttacksBridgeImpl implements BlocksAttacksBridge { + + @Override + public DamageReduction.Builder blocksAttacksDamageReduction() { + return new PaperDamageReduction.BuilderImpl(); + } + + @Override + public ItemDamageFunction.Builder blocksAttacksItemDamageFunction() { + return new PaperItemDamageFunction.BuilderImpl(); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java new file mode 100644 index 000000000..7da287938 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java @@ -0,0 +1,87 @@ +package io.papermc.paper.datacomponent.item.blocksattacks; + +import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.set.PaperRegistrySets; +import io.papermc.paper.registry.set.RegistryKeySet; +import net.minecraft.core.HolderSet; +import net.minecraft.core.registries.Registries; +import org.bukkit.craftbukkit.util.Handleable; +import org.bukkit.damage.DamageType; +import org.checkerframework.checker.index.qual.Positive; +import org.jetbrains.annotations.Nullable; +import java.util.Optional; + +public record PaperDamageReduction( + net.minecraft.world.item.component.BlocksAttacks.DamageReduction impl +) implements DamageReduction, Handleable { + + @Override + public net.minecraft.world.item.component.BlocksAttacks.DamageReduction getHandle() { + return this.impl; + } + + @Override + public @Nullable RegistryKeySet type() { + return this.impl.type().map((set) -> PaperRegistrySets.convertToApi(RegistryKey.DAMAGE_TYPE, set)).orElse(null); + } + + @Override + public @Positive float horizontalBlockingAngle() { + return this.impl.horizontalBlockingAngle(); + } + + @Override + public float base() { + return this.impl.base(); + } + + @Override + public float factor() { + return this.impl.factor(); + } + + static final class BuilderImpl implements Builder { + + private Optional> type = Optional.empty(); + private float horizontalBlockingAngle = 90f; + private float base = 0; + private float factor = 0; + + @Override + public Builder type(final @Nullable RegistryKeySet type) { + this.type = Optional.ofNullable(type) + .map((set) -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, net.minecraft.server.MinecraftServer.getServer().registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE).lookupProvider, set)); + return this; + } + + @Override + public Builder horizontalBlockingAngle(@Positive final float horizontalBlockingAngle) { + Preconditions.checkArgument(horizontalBlockingAngle > 0, "horizontalBlockingAngle must be positive and not zero, was %s", horizontalBlockingAngle); + this.horizontalBlockingAngle = horizontalBlockingAngle; + return this; + } + + @Override + public Builder base(final float base) { + this.base = base; + return this; + } + + @Override + public Builder factor(final float factor) { + this.factor = factor; + return this; + } + + @Override + public DamageReduction build() { + return new PaperDamageReduction(new net.minecraft.world.item.component.BlocksAttacks.DamageReduction( + this.horizontalBlockingAngle, + this.type, + this.base, + this.factor + )); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java new file mode 100644 index 000000000..515eec159 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java @@ -0,0 +1,70 @@ +package io.papermc.paper.datacomponent.item.blocksattacks; + +import com.google.common.base.Preconditions; +import org.bukkit.craftbukkit.util.Handleable; +import org.checkerframework.checker.index.qual.NonNegative; + +public record PaperItemDamageFunction( + net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction impl +) implements ItemDamageFunction, Handleable { + + @Override + public net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction getHandle() { + return this.impl; + } + + @Override + public @NonNegative float threshold() { + return this.impl.threshold(); + } + + @Override + public float base() { + return this.impl.base(); + } + + @Override + public float factor() { + return this.impl.factor(); + } + + @Override + public int damageToApply(final float damage) { + return this.impl.apply(damage); + } + + static final class BuilderImpl implements Builder { + + private float threshold; + private float base; + private float factor; + + @Override + public Builder threshold(@NonNegative final float threshold) { + Preconditions.checkArgument(threshold >= 0, "threshold must be non-negative, was %s", threshold); + this.threshold = threshold; + return this; + } + + @Override + public Builder base(final float base) { + this.base = base; + return this; + } + + @Override + public Builder factor(final float factor) { + this.factor = factor; + return this; + } + + @Override + public ItemDamageFunction build() { + return new PaperItemDamageFunction(new net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction( + this.threshold, + this.base, + this.factor + )); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/package-info.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/package-info.java new file mode 100644 index 000000000..d0fca5341 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/package-info.java @@ -0,0 +1,7 @@ +/** + * Relating to block attacks for components. + */ +@NullMarked +package io.papermc.paper.datacomponent.item.blocksattacks; + +import org.jspecify.annotations.NullMarked; diff --git a/paper-server/src/main/java/io/papermc/paper/entity/PaperSchoolableFish.java b/paper-server/src/main/java/io/papermc/paper/entity/PaperSchoolableFish.java index 41bf71d11..04c8213ae 100644 --- a/paper-server/src/main/java/io/papermc/paper/entity/PaperSchoolableFish.java +++ b/paper-server/src/main/java/io/papermc/paper/entity/PaperSchoolableFish.java @@ -13,7 +13,7 @@ public class PaperSchoolableFish extends CraftFish implements SchoolableFish { @Override public AbstractSchoolingFish getHandle() { - return (AbstractSchoolingFish) super.getHandle(); + return (AbstractSchoolingFish) this.entity; } @Override diff --git a/paper-server/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java b/paper-server/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java index 28857d0c9..fbad4a224 100644 --- a/paper-server/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java +++ b/paper-server/src/main/java/io/papermc/paper/pluginremap/PluginRemapper.java @@ -75,7 +75,11 @@ public final class PluginRemapper { return null; } - return new PluginRemapper(pluginsDir); + try { + return new PluginRemapper(pluginsDir); + } catch (final Exception e) { + throw new RuntimeException("Failed to create PluginRemapper, try deleting the '" + pluginsDir.resolve(PAPER_REMAPPED) + "' directory", e); + } } public void shutdown() { diff --git a/paper-server/src/main/java/io/papermc/paper/pluginremap/RemappedPluginIndex.java b/paper-server/src/main/java/io/papermc/paper/pluginremap/RemappedPluginIndex.java index 86fc60452..1a2e8902c 100644 --- a/paper-server/src/main/java/io/papermc/paper/pluginremap/RemappedPluginIndex.java +++ b/paper-server/src/main/java/io/papermc/paper/pluginremap/RemappedPluginIndex.java @@ -8,6 +8,7 @@ import io.papermc.paper.util.MappingEnvironment; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -52,32 +53,35 @@ class RemappedPluginIndex { try { Files.createDirectories(this.dir); } catch (final IOException ex) { - throw new RuntimeException(ex); + throw new UncheckedIOException(ex); } } this.indexFile = dir.resolve(INDEX_FILE_NAME); if (Files.isRegularFile(this.indexFile)) { - try { - this.state = this.readIndex(); - } catch (final IOException e) { - throw new RuntimeException(e); - } + this.state = this.readIndex(); } else { this.state = new State(); } } - private State readIndex() throws IOException { + private State readIndex() { final State state; try (final BufferedReader reader = Files.newBufferedReader(this.indexFile)) { state = GSON.fromJson(reader, State.class); + } catch (final Exception ex) { + throw new RuntimeException("Failed to read index file '" + this.indexFile + "'", ex); } // If mappings have changed, delete all cached files and create a new index if (!state.mappingsHash.equals(MappingEnvironment.mappingsHash())) { for (final String fileName : state.hashes.values()) { - Files.deleteIfExists(this.dir.resolve(fileName)); + final Path path = this.dir.resolve(fileName); + try { + Files.deleteIfExists(path); + } catch (final IOException ex) { + throw new UncheckedIOException("Failed to delete no longer needed file '" + path + "'", ex); + } } return new State(); } @@ -111,10 +115,11 @@ class RemappedPluginIndex { } iterator.remove(); + final Path filePath = this.dir.resolve(fileName); try { - Files.deleteIfExists(this.dir.resolve(fileName)); + Files.deleteIfExists(filePath); } catch (final IOException ex) { - throw new RuntimeException(ex); + throw new UncheckedIOException("Failed to delete no longer needed file '" + filePath + "'", ex); } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java index 01dbd27a3..b0d34b749 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -5,10 +5,16 @@ import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.datacomponent.DataComponentTypes; import io.papermc.paper.datacomponent.PaperDataComponentType; import io.papermc.paper.registry.data.PaperBannerPatternRegistryEntry; +import io.papermc.paper.registry.data.PaperCatTypeRegistryEntry; +import io.papermc.paper.registry.data.PaperChickenVariantRegistryEntry; +import io.papermc.paper.registry.data.PaperCowVariantRegistryEntry; import io.papermc.paper.registry.data.PaperDamageTypeRegistryEntry; import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; +import io.papermc.paper.registry.data.PaperFrogVariantRegistryEntry; import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; +import io.papermc.paper.registry.data.PaperPigVariantRegistryEntry; +import io.papermc.paper.registry.data.PaperWolfVariantRegistryEntry; import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.tag.TagKey; @@ -111,18 +117,18 @@ public final class PaperRegistries { start(Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL).craft(TrimMaterial.class, CraftTrimMaterial::new, true).build().delayed(), start(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN).craft(TrimPattern.class, CraftTrimPattern::new, true).build().delayed(), start(Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE).craft(DamageType.class, CraftDamageType::new).writable(PaperDamageTypeRegistryEntry.PaperBuilder::new).delayed(), - start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).build().delayed(), + start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).writable(PaperWolfVariantRegistryEntry.PaperBuilder::new).delayed(), start(Registries.WOLF_SOUND_VARIANT, RegistryKey.WOLF_SOUND_VARIANT).craft(Wolf.SoundVariant.class, CraftWolf.CraftSoundVariant::new).build(), start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).serializationUpdater(FieldRename.ENCHANTMENT_RENAME).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).delayed(), start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(), start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new, true).writable(PaperBannerPatternRegistryEntry.PaperBuilder::new).delayed(), start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new, true).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::new, true).build().delayed(), - start(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT).craft(Cat.Type.class, CraftCat.CraftType::new).build().delayed(), - start(Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT).craft(Frog.Variant.class, CraftFrog.CraftVariant::new).build().delayed(), - start(Registries.CHICKEN_VARIANT, RegistryKey.CHICKEN_VARIANT).craft(Chicken.Variant.class, CraftChicken.CraftVariant::new).build(), - start(Registries.COW_VARIANT, RegistryKey.COW_VARIANT).craft(Cow.Variant.class, CraftCow.CraftVariant::new).build(), - start(Registries.PIG_VARIANT, RegistryKey.PIG_VARIANT).craft(Pig.Variant.class, CraftPig.CraftVariant::new).build(), + start(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT).craft(Cat.Type.class, CraftCat.CraftType::new).writable(PaperCatTypeRegistryEntry.PaperBuilder::new).delayed(), + start(Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT).craft(Frog.Variant.class, CraftFrog.CraftVariant::new).writable(PaperFrogVariantRegistryEntry.PaperBuilder::new).delayed(), + start(Registries.CHICKEN_VARIANT, RegistryKey.CHICKEN_VARIANT).craft(Chicken.Variant.class, CraftChicken.CraftVariant::new).writable(PaperChickenVariantRegistryEntry.PaperBuilder::new), + start(Registries.COW_VARIANT, RegistryKey.COW_VARIANT).craft(Cow.Variant.class, CraftCow.CraftVariant::new).writable(PaperCowVariantRegistryEntry.PaperBuilder::new), + start(Registries.PIG_VARIANT, RegistryKey.PIG_VARIANT).craft(Pig.Variant.class, CraftPig.CraftVariant::new).writable(PaperPigVariantRegistryEntry.PaperBuilder::new), // api-only start(Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE).apiOnly(PaperSimpleRegistry::entityType), diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperCatTypeRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperCatTypeRegistryEntry.java new file mode 100644 index 000000000..c82d9bdfc --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperCatTypeRegistryEntry.java @@ -0,0 +1,60 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.data.util.Conversions; +import net.minecraft.world.entity.animal.CatVariant; +import net.minecraft.world.entity.variant.SpawnPrioritySelectors; +import org.bukkit.entity.Cat; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperCatTypeRegistryEntry implements CatTypeRegistryEntry { + + protected net.minecraft.core.@Nullable ClientAsset clientTextureAsset; + protected SpawnPrioritySelectors spawnConditions; + + protected final Conversions conversions; + + public PaperCatTypeRegistryEntry( + final Conversions conversions, + final @Nullable CatVariant internal + ) { + this.conversions = conversions; + if (internal == null) { + this.spawnConditions = SpawnPrioritySelectors.EMPTY; + return; + } + + this.clientTextureAsset = internal.assetInfo(); + this.spawnConditions = internal.spawnConditions(); + } + + @Override + public ClientTextureAsset clientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.clientTextureAsset, "clientTextureAsset")); + } + + public static final class PaperBuilder extends PaperCatTypeRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable CatVariant internal) { + super(conversions, internal); + } + + @Override + public Builder clientTextureAsset(final ClientTextureAsset clientTextureAsset) { + this.clientTextureAsset = this.conversions.asVanilla(asArgument(clientTextureAsset, "clientTextureAsset")); + return this; + } + + @Override + public CatVariant build() { + return new CatVariant( + asConfigured(this.clientTextureAsset, "clientTextureAsset"), + asConfigured(this.spawnConditions, "spawnConditions") + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperChickenVariantRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperChickenVariantRegistryEntry.java new file mode 100644 index 000000000..281dfe8e5 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperChickenVariantRegistryEntry.java @@ -0,0 +1,80 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.data.util.Conversions; +import net.minecraft.world.entity.animal.ChickenVariant; +import net.minecraft.world.entity.variant.ModelAndTexture; +import net.minecraft.world.entity.variant.SpawnPrioritySelectors; +import org.bukkit.entity.Chicken; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperChickenVariantRegistryEntry implements ChickenVariantRegistryEntry { + + protected ChickenVariant.@Nullable ModelType model; + protected net.minecraft.core.@Nullable ClientAsset clientTextureAsset; + protected SpawnPrioritySelectors spawnConditions; + + protected final Conversions conversions; + + public PaperChickenVariantRegistryEntry( + final Conversions conversions, + final @Nullable ChickenVariant internal + ) { + this.conversions = conversions; + if (internal == null) { + this.spawnConditions = SpawnPrioritySelectors.EMPTY; + return; + } + + this.clientTextureAsset = internal.modelAndTexture().asset(); + this.model = internal.modelAndTexture().model(); + this.spawnConditions = internal.spawnConditions(); + } + + @Override + public ClientTextureAsset clientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.clientTextureAsset, "clientTextureAsset")); + } + + @Override + public Model model() { + return switch (asConfigured(this.model, "model")) { + case NORMAL -> Model.NORMAL; + case COLD -> Model.COLD; + }; + } + + public static final class PaperBuilder extends PaperChickenVariantRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable ChickenVariant internal) { + super(conversions, internal); + } + + @Override + public Builder clientTextureAsset(final ClientTextureAsset clientTextureAsset) { + this.clientTextureAsset = this.conversions.asVanilla(asArgument(clientTextureAsset, "clientTextureAsset")); + return this; + } + + @Override + public Builder model(final Model model) { + this.model = switch (asArgument(model, "model")) { + case NORMAL -> ChickenVariant.ModelType.NORMAL; + case COLD -> ChickenVariant.ModelType.COLD; + }; + return this; + } + + @Override + public ChickenVariant build() { + return new ChickenVariant( + new ModelAndTexture<>(asConfigured(this.model, "model"), asConfigured(this.clientTextureAsset, "clientTextureAsset")), + asConfigured(this.spawnConditions, "spawnConditions") + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperCowVariantRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperCowVariantRegistryEntry.java new file mode 100644 index 000000000..25d5e3198 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperCowVariantRegistryEntry.java @@ -0,0 +1,82 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.data.util.Conversions; +import net.minecraft.world.entity.animal.CowVariant; +import net.minecraft.world.entity.variant.ModelAndTexture; +import net.minecraft.world.entity.variant.SpawnPrioritySelectors; +import org.bukkit.entity.Cow; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperCowVariantRegistryEntry implements CowVariantRegistryEntry { + + protected CowVariant.@Nullable ModelType model = null; + protected net.minecraft.core.@Nullable ClientAsset clientTextureAsset = null; + protected SpawnPrioritySelectors spawnConditions; + + protected final Conversions conversions; + + public PaperCowVariantRegistryEntry( + final Conversions conversions, + final @Nullable CowVariant internal + ) { + this.conversions = conversions; + if (internal == null) { + this.spawnConditions = SpawnPrioritySelectors.EMPTY; + return; + } + + this.clientTextureAsset = internal.modelAndTexture().asset(); + this.model = internal.modelAndTexture().model(); + this.spawnConditions = internal.spawnConditions(); + } + + @Override + public ClientTextureAsset clientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.clientTextureAsset, "clientTextureAsset")); + } + + @Override + public Model model() { + return switch (asConfigured(this.model, "model")) { + case NORMAL -> Model.NORMAL; + case COLD -> Model.COLD; + case WARM -> Model.WARM; + }; + } + + public static final class PaperBuilder extends PaperCowVariantRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable CowVariant internal) { + super(conversions, internal); + } + + @Override + public Builder clientTextureAsset(final ClientTextureAsset clientTextureAsset) { + this.clientTextureAsset = this.conversions.asVanilla(asArgument(clientTextureAsset, "clientTextureAsset")); + return this; + } + + @Override + public Builder model(final Model model) { + this.model = switch (asArgument(model, "model")) { + case NORMAL -> CowVariant.ModelType.NORMAL; + case COLD -> CowVariant.ModelType.COLD; + case WARM -> CowVariant.ModelType.WARM; + }; + return this; + } + + @Override + public CowVariant build() { + return new CowVariant( + new ModelAndTexture<>(asConfigured(this.model, "model"), asConfigured(this.clientTextureAsset, "clientTextureAsset")), + this.spawnConditions + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperFrogVariantRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperFrogVariantRegistryEntry.java new file mode 100644 index 000000000..953beb789 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperFrogVariantRegistryEntry.java @@ -0,0 +1,60 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.data.util.Conversions; +import net.minecraft.world.entity.animal.frog.FrogVariant; +import net.minecraft.world.entity.variant.SpawnPrioritySelectors; +import org.bukkit.entity.Frog; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperFrogVariantRegistryEntry implements FrogVariantRegistryEntry { + + protected net.minecraft.core.@Nullable ClientAsset clientTextureAsset; + protected SpawnPrioritySelectors spawnConditions; + + protected final Conversions conversions; + + public PaperFrogVariantRegistryEntry( + final Conversions conversions, + final @Nullable FrogVariant internal + ) { + this.conversions = conversions; + if (internal == null) { + spawnConditions = SpawnPrioritySelectors.EMPTY; + return; + } + + this.clientTextureAsset = internal.assetInfo(); + this.spawnConditions = internal.spawnConditions(); + } + + @Override + public ClientTextureAsset clientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.clientTextureAsset, "clientTextureAsset")); + } + + public static final class PaperBuilder extends PaperFrogVariantRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable FrogVariant internal) { + super(conversions, internal); + } + + @Override + public Builder clientTextureAsset(final ClientTextureAsset clientTextureAsset) { + this.clientTextureAsset = this.conversions.asVanilla(asArgument(clientTextureAsset, "clientTextureAsset")); + return this; + } + + @Override + public FrogVariant build() { + return new FrogVariant( + asConfigured(this.clientTextureAsset, "clientTextureAsset"), + asConfigured(this.spawnConditions, "spawnConditions") + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperPigVariantRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperPigVariantRegistryEntry.java new file mode 100644 index 000000000..c7e6c68b7 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperPigVariantRegistryEntry.java @@ -0,0 +1,80 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.data.util.Conversions; +import net.minecraft.world.entity.animal.PigVariant; +import net.minecraft.world.entity.variant.ModelAndTexture; +import net.minecraft.world.entity.variant.SpawnPrioritySelectors; +import org.bukkit.entity.Pig; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperPigVariantRegistryEntry implements PigVariantRegistryEntry { + + protected PigVariant.@Nullable ModelType model; + protected net.minecraft.core.@Nullable ClientAsset clientTextureAsset; + protected SpawnPrioritySelectors spawnConditions; + + protected final Conversions conversions; + + public PaperPigVariantRegistryEntry( + final Conversions conversions, + final @Nullable PigVariant internal + ) { + this.conversions = conversions; + if (internal == null) { + spawnConditions = SpawnPrioritySelectors.EMPTY; + return; + } + + this.clientTextureAsset = internal.modelAndTexture().asset(); + this.model = internal.modelAndTexture().model(); + this.spawnConditions = internal.spawnConditions(); + } + + @Override + public ClientTextureAsset clientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.clientTextureAsset, "clientTextureAsset")); + } + + @Override + public Model model() { + return switch (asConfigured(this.model, "model")) { + case NORMAL -> Model.NORMAL; + case COLD -> Model.COLD; + }; + } + + public static final class PaperBuilder extends PaperPigVariantRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable PigVariant internal) { + super(conversions, internal); + } + + @Override + public Builder clientTextureAsset(final ClientTextureAsset clientTextureAsset) { + this.clientTextureAsset = this.conversions.asVanilla(asArgument(clientTextureAsset, "clientTextureAsset")); + return this; + } + + @Override + public Builder model(final Model model) { + this.model = switch (asArgument(model, "model")) { + case NORMAL -> PigVariant.ModelType.NORMAL; + case COLD -> PigVariant.ModelType.COLD; + }; + return this; + } + + @Override + public PigVariant build() { + return new PigVariant( + new ModelAndTexture<>(asConfigured(this.model, "model"), asConfigured(this.clientTextureAsset, "clientTextureAsset")), + asConfigured(this.spawnConditions, "spawnConditions") + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperWolfVariantRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperWolfVariantRegistryEntry.java new file mode 100644 index 000000000..ca14e9d62 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperWolfVariantRegistryEntry.java @@ -0,0 +1,90 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.data.util.Conversions; +import net.minecraft.world.entity.animal.wolf.WolfVariant; +import net.minecraft.world.entity.variant.SpawnPrioritySelectors; +import org.bukkit.entity.Wolf; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperWolfVariantRegistryEntry implements WolfVariantRegistryEntry { + + protected net.minecraft.core.@Nullable ClientAsset angryClientTextureAsset; + protected net.minecraft.core.@Nullable ClientAsset wildClientTextureAsset; + protected net.minecraft.core.@Nullable ClientAsset tameClientTextureAsset; + protected SpawnPrioritySelectors spawnConditions; + + protected final Conversions conversions; + + public PaperWolfVariantRegistryEntry( + final Conversions conversions, + final @Nullable WolfVariant internal + ) { + this.conversions = conversions; + if (internal == null) { + this.spawnConditions = SpawnPrioritySelectors.EMPTY; + return; + } + + this.angryClientTextureAsset = internal.assetInfo().angry(); + this.wildClientTextureAsset = internal.assetInfo().wild(); + this.tameClientTextureAsset = internal.assetInfo().tame(); + this.spawnConditions = internal.spawnConditions(); + } + + @Override + public ClientTextureAsset angryClientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.angryClientTextureAsset, "angryClientTextureAsset")); + } + + @Override + public ClientTextureAsset wildClientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.wildClientTextureAsset, "wildClientTextureAsset")); + } + + @Override + public ClientTextureAsset tameClientTextureAsset() { + return this.conversions.asBukkit(asConfigured(this.tameClientTextureAsset, "tameClientTextureAsset")); + } + + public static final class PaperBuilder extends PaperWolfVariantRegistryEntry implements Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable WolfVariant internal) { + super(conversions, internal); + } + + @Override + public Builder angryClientTextureAsset(final ClientTextureAsset angryClientTextureAsset) { + this.angryClientTextureAsset = this.conversions.asVanilla(asArgument(angryClientTextureAsset, "angryClientTextureAsset")); + return this; + } + + @Override + public Builder wildClientTextureAsset(final ClientTextureAsset wildClientTextureAsset) { + this.wildClientTextureAsset = this.conversions.asVanilla(asArgument(wildClientTextureAsset, "wildClientTextureAsset")); + return this; + } + + @Override + public Builder tameClientTextureAsset(final ClientTextureAsset tameClientTextureAsset) { + this.tameClientTextureAsset = this.conversions.asVanilla(asArgument(tameClientTextureAsset, "tameClientTextureAsset")); + return this; + } + + @Override + public WolfVariant build() { + return new WolfVariant( + new WolfVariant.AssetInfo( + asConfigured(this.wildClientTextureAsset, "wildClientTextureAsset"), + asConfigured(this.tameClientTextureAsset, "tameClientTextureAsset"), + asConfigured(this.angryClientTextureAsset, "angryClientTextureAsset") + ), + asConfigured(this.spawnConditions, "spawnConditions") + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java b/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java index b1710da83..b6a9fd509 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java @@ -2,8 +2,10 @@ package io.papermc.paper.registry.data.util; import com.google.common.base.Preconditions; import com.mojang.serialization.JavaOps; +import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.adventure.WrapperAwareSerializer; import java.util.Optional; +import io.papermc.paper.registry.data.client.ClientTextureAsset; import net.kyori.adventure.text.Component; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; @@ -33,7 +35,6 @@ public class Conversions { return globalInstance; } - private final RegistryOps.RegistryInfoLookup lookup; private final WrapperAwareSerializer serializer; @@ -55,4 +56,18 @@ public class Conversions { public Component asAdventure(final net.minecraft.network.chat.@Nullable Component vanilla) { return vanilla == null ? Component.empty() : this.serializer.deserialize(vanilla); } + + public ClientTextureAsset asBukkit(final net.minecraft.core.@Nullable ClientAsset clientTextureAsset) { + return clientTextureAsset == null ? null : ClientTextureAsset.clientTextureAsset( + PaperAdventure.asAdventure(clientTextureAsset.id()), + PaperAdventure.asAdventure(clientTextureAsset.texturePath()) + ); + } + + public net.minecraft.core.ClientAsset asVanilla(final @Nullable ClientTextureAsset clientTextureAsset) { + return clientTextureAsset == null ? null : new net.minecraft.core.ClientAsset( + PaperAdventure.asVanilla(clientTextureAsset.identifier()), + PaperAdventure.asVanilla(clientTextureAsset.texturePath()) + ); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/util/MCUtil.java b/paper-server/src/main/java/io/papermc/paper/util/MCUtil.java index 8756aedc6..8492a0688 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/MCUtil.java +++ b/paper-server/src/main/java/io/papermc/paper/util/MCUtil.java @@ -103,6 +103,18 @@ public final class MCUtil { run.run(); } + public static double sanitizeNanInf(final double value, final double defaultValue) { + return Double.isNaN(value) || Double.isInfinite(value) ? defaultValue : value; + } + + public static Vec3 sanitizeNanInf(final Vec3 vec3, final double defaultValue) { + return new Vec3( + sanitizeNanInf(vec3.x, defaultValue), + sanitizeNanInf(vec3.y, defaultValue), + sanitizeNanInf(vec3.z, defaultValue) + ); + } + public static T ensureMain(Supplier run) { return ensureMain(null, run); } @@ -140,6 +152,20 @@ public final class MCUtil { return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2); } + /** + * Converts a NMS World/Vector to Bukkit Location + */ + public static Location toLocation(Level world, Vec3 pos) { + return new Location(world.getWorld(), pos.x(), pos.y(), pos.z()); + } + + /** + * Converts a NMS World/Vector to Bukkit Location + */ + public static Location toLocation(Level world, Vec3 pos, float yaw, float pitch) { + return new Location(world.getWorld(), pos.x(), pos.y(), pos.z(), yaw, pitch); + } + public static BlockPos toBlockPos(Position pos) { return new BlockPos(pos.blockX(), pos.blockY(), pos.blockZ()); } diff --git a/paper-server/src/main/java/io/papermc/paper/world/damagesource/PaperCombatEntryWrapper.java b/paper-server/src/main/java/io/papermc/paper/world/damagesource/PaperCombatEntryWrapper.java new file mode 100644 index 000000000..354c57fde --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/world/damagesource/PaperCombatEntryWrapper.java @@ -0,0 +1,32 @@ +package io.papermc.paper.world.damagesource; + +import net.minecraft.Optionull; +import org.bukkit.craftbukkit.damage.CraftDamageSource; +import org.bukkit.damage.DamageSource; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@NullMarked +public record PaperCombatEntryWrapper(net.minecraft.world.damagesource.CombatEntry handle) implements CombatEntry { + + @Override + public DamageSource getDamageSource() { + return new CraftDamageSource(this.handle.source()); + } + + @Override + public float getDamage() { + return this.handle.damage(); + } + + @Override + public @Nullable FallLocationType getFallLocationType() { + return Optionull.map(this.handle.fallLocation(), PaperCombatTrackerWrapper::minecraftToPaper); + } + + @Override + public float getFallDistance() { + return this.handle.fallDistance(); + } + +} diff --git a/paper-server/src/main/java/io/papermc/paper/world/damagesource/PaperCombatTrackerWrapper.java b/paper-server/src/main/java/io/papermc/paper/world/damagesource/PaperCombatTrackerWrapper.java new file mode 100644 index 000000000..43afa79e9 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/world/damagesource/PaperCombatTrackerWrapper.java @@ -0,0 +1,111 @@ +package io.papermc.paper.world.damagesource; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import io.papermc.paper.adventure.PaperAdventure; +import java.util.ArrayList; +import java.util.List; +import net.kyori.adventure.text.Component; +import net.minecraft.Optionull; +import net.minecraft.Util; +import net.minecraft.world.damagesource.FallLocation; +import org.bukkit.entity.LivingEntity; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@NullMarked +public record PaperCombatTrackerWrapper( + net.minecraft.world.damagesource.CombatTracker handle +) implements CombatTracker { + + @Override + public LivingEntity getEntity() { + return this.handle.mob.getBukkitLivingEntity(); + } + + @Override + public List getCombatEntries() { + final List combatEntries = new ArrayList<>(this.handle.entries.size()); + this.handle.entries.forEach(combatEntry -> combatEntries.add(new PaperCombatEntryWrapper(combatEntry))); + return combatEntries; + } + + @Override + public void setCombatEntries(final List combatEntries) { + this.handle.entries.clear(); + combatEntries.forEach(combatEntry -> this.handle.entries.add(((PaperCombatEntryWrapper) combatEntry).handle())); + } + + @Override + public @Nullable CombatEntry computeMostSignificantFall() { + final net.minecraft.world.damagesource.CombatEntry combatEntry = this.handle.getMostSignificantFall(); + return combatEntry == null ? null : new PaperCombatEntryWrapper(combatEntry); + } + + @Override + public boolean isInCombat() { + return this.handle.inCombat; + } + + @Override + public boolean isTakingDamage() { + return this.handle.takingDamage; + } + + @Override + public int getCombatDuration() { + return this.handle.getCombatDuration(); + } + + @Override + public void addCombatEntry(final CombatEntry combatEntry) { + final net.minecraft.world.damagesource.CombatEntry entry = ((PaperCombatEntryWrapper) combatEntry).handle(); + this.handle.recordDamageAndCheckCombatState(entry); + } + + @Override + public Component getDeathMessage() { + return PaperAdventure.asAdventure(this.handle.getDeathMessage()); + } + + @Override + public void resetCombatState() { + this.handle.resetCombatState(); + } + + @Override + public FallLocationType calculateFallLocationType() { + final FallLocation fallLocation = FallLocation.getCurrentFallLocation(this.handle().mob); + return Optionull.map(fallLocation, PaperCombatTrackerWrapper::minecraftToPaper); + } + + private static final BiMap FALL_LOCATION_MAPPING = Util.make(() -> { + final BiMap map = HashBiMap.create(8); + map.put(FallLocation.GENERIC, FallLocationType.GENERIC); + map.put(FallLocation.LADDER, FallLocationType.LADDER); + map.put(FallLocation.VINES, FallLocationType.VINES); + map.put(FallLocation.WEEPING_VINES, FallLocationType.WEEPING_VINES); + map.put(FallLocation.TWISTING_VINES, FallLocationType.TWISTING_VINES); + map.put(FallLocation.SCAFFOLDING, FallLocationType.SCAFFOLDING); + map.put(FallLocation.OTHER_CLIMBABLE, FallLocationType.OTHER_CLIMBABLE); + map.put(FallLocation.WATER, FallLocationType.WATER); + return map; + }); + + public static FallLocation paperToMinecraft(final FallLocationType fallLocationType) { + final FallLocation fallLocation = FALL_LOCATION_MAPPING.inverse().get(fallLocationType); + if (fallLocation == null) { + throw new IllegalArgumentException("Unknown fall location type: " + fallLocationType.id()); + } + return fallLocation; + } + + public static FallLocationType minecraftToPaper(final FallLocation fallLocation) { + final FallLocationType fallLocationType = FALL_LOCATION_MAPPING.get(fallLocation); + if (fallLocationType == null) { + throw new IllegalArgumentException("Unknown fall location: " + fallLocation.id()); + } + return fallLocationType; + } + +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java index ab3043a8d..81a738b05 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java @@ -1,14 +1,16 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; +import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.util.Holderable; +import net.kyori.adventure.text.Component; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.world.item.Instrument; import org.bukkit.MusicInstrument; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; +import org.bukkit.Sound; import org.jetbrains.annotations.NotNull; public class CraftMusicInstrument extends MusicInstrument implements io.papermc.paper.util.Holderable { @@ -26,19 +28,19 @@ public class CraftMusicInstrument extends MusicInstrument implements io.papermc. } public static Holder bukkitToMinecraftHolder(MusicInstrument bukkit) { - return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.INSTRUMENT); // Paper - switch to Holder + return CraftRegistry.bukkitToMinecraftHolder(bukkit, Registries.INSTRUMENT); } - public static Object bukkitToString(MusicInstrument bukkit) { // Paper - switch to Holder + public static Object bukkitToString(MusicInstrument bukkit) { Preconditions.checkArgument(bukkit != null); - return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.DIRECT_CODEC); // Paper - switch to Holder + return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.DIRECT_CODEC); } - public static MusicInstrument stringToBukkit(Object string) { // Paper - switch to Holder + public static MusicInstrument stringToBukkit(Object string) { Preconditions.checkArgument(string != null); - return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(string, Instrument.CODEC, RegistryKey.INSTRUMENT); // Paper - switch to Holder + return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(string, Instrument.CODEC, RegistryKey.INSTRUMENT); } @Override @@ -63,8 +65,28 @@ public class CraftMusicInstrument extends MusicInstrument implements io.papermc. } @Override - public Holder getHolder() { // Paper - switch to Holder - return this.holder; // Paper - switch to Holder + public Holder getHolder() { + return this.holder; + } + + @Override + public float getDuration() { + return this.getHandle().useDuration(); + } + + @Override + public float getRange() { + return this.getHandle().range(); + } + + @Override + public Component description() { + return PaperAdventure.asAdventure(this.getHandle().description()); + } + + @Override + public Sound getSound() { + return CraftSound.minecraftHolderToBukkit(this.getHandle().soundEvent()); } @NotNull @@ -76,7 +98,7 @@ public class CraftMusicInstrument extends MusicInstrument implements io.papermc. @Override public @NotNull String translationKey() { if (!(this.getHandle().description().getContents() instanceof final net.minecraft.network.chat.contents.TranslatableContents translatableContents)) { - throw new UnsupportedOperationException("Description isn't translatable!"); // Paper + throw new UnsupportedOperationException("Description isn't translatable!"); } return translatableContents.getKey(); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index 79e226da3..43ae147ae 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -6,7 +6,6 @@ import java.time.Duration; import java.time.Instant; import java.util.Date; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.UUID; import net.minecraft.core.GlobalPos; @@ -33,8 +32,6 @@ import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; -import org.bukkit.metadata.MetadataValue; -import org.bukkit.plugin.Plugin; @SerializableAs("Player") public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable { @@ -362,18 +359,23 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } @Override - public Location getRespawnLocation() { - CompoundTag data = this.getData(); + public Location getRespawnLocation(final boolean loadLocationAndValidate) { + final CompoundTag data = this.getData(); if (data == null) return null; final ServerPlayer.RespawnConfig respawnConfig = data.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null); - if (respawnConfig != null) { - final ServerLevel level = this.server.console.getLevel(respawnConfig.dimension()); - if (level != null) { - return CraftLocation.toBukkit(respawnConfig.pos(), level.getWorld(), respawnConfig.angle(), 0); - } + if (respawnConfig == null) return null; + + final ServerLevel level = this.server.console.getLevel(respawnConfig.dimension()); + if (level == null) return null; + + if (!loadLocationAndValidate) { + return CraftLocation.toBukkit(respawnConfig.pos(), level.getWorld(), respawnConfig.angle(), 0); } - return null; + + return ServerPlayer.findRespawnAndUseSpawnBlock(level, respawnConfig, false) + .map(resolvedPos -> CraftLocation.toBukkit(resolvedPos.position(), level.getWorld(), resolvedPos.yaw(), 0)) + .orElse(null); } private ServerStatsCounter getStatisticManager() { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 6ce00157d..ad561f0a8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -12,6 +12,8 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Dynamic; import com.mojang.serialization.Lifecycle; +import io.papermc.paper.configuration.PaperServerConfiguration; +import io.papermc.paper.configuration.ServerConfiguration; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; @@ -40,6 +42,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import javax.imageio.ImageIO; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.Optionull; import net.minecraft.advancements.AdvancementHolder; import net.minecraft.commands.CommandSourceStack; @@ -87,6 +91,7 @@ import net.minecraft.world.inventory.ResultContainer; import net.minecraft.world.inventory.TransientCraftingContainer; import net.minecraft.world.item.Item; import net.minecraft.world.item.MapItem; +import net.minecraft.world.item.crafting.CraftingInput; import net.minecraft.world.item.crafting.CraftingRecipe; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.item.crafting.RecipeType; @@ -113,7 +118,6 @@ import net.minecraft.world.level.validation.ContentValidationException; import net.minecraft.world.phys.Vec3; import org.bukkit.BanList; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Keyed; import org.bukkit.Location; @@ -311,6 +315,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; public final io.papermc.paper.SparksFly spark; + private final ServerConfiguration serverConfig = new PaperServerConfiguration(); // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); @@ -1717,25 +1722,31 @@ public final class CraftServer implements Server { private CraftItemCraftResult createItemCraftResult(Optional> recipe, ItemStack itemStack, CraftingContainer inventoryCrafting) { CraftItemCraftResult craftItemResult = new CraftItemCraftResult(itemStack); - recipe.map((holder) -> holder.value().getRemainingItems(inventoryCrafting.asCraftInput())).ifPresent((remainingItems) -> { + // tl;dr: this is an API adopted implementation of ResultSlot#onTake + final CraftingInput.Positioned positionedCraftInput = inventoryCrafting.asPositionedCraftInput(); + final CraftingInput craftingInput = positionedCraftInput.input(); + recipe.map((holder) -> holder.value().getRemainingItems(craftingInput)).ifPresent((remainingItems) -> { // Set the resulting matrix items and overflow items - for (int i = 0; i < remainingItems.size(); ++i) { - net.minecraft.world.item.ItemStack itemstack1 = inventoryCrafting.getItem(i); - net.minecraft.world.item.ItemStack itemstack2 = remainingItems.get(i); + for (int height = 0; height < craftingInput.height(); height++) { + for (int width = 0; width < craftingInput.width(); width++) { + final int inventorySlot = width + positionedCraftInput.left() + (height + positionedCraftInput.top()) * inventoryCrafting.getWidth(); + net.minecraft.world.item.ItemStack itemInMenu = inventoryCrafting.getItem(inventorySlot); + net.minecraft.world.item.ItemStack remainingItem = remainingItems.get(width + height * craftingInput.width()); - if (!itemstack1.isEmpty()) { - inventoryCrafting.removeItem(i, 1); - itemstack1 = inventoryCrafting.getItem(i); - } + if (!itemInMenu.isEmpty()) { + inventoryCrafting.removeItem(inventorySlot, 1); + itemInMenu = inventoryCrafting.getItem(inventorySlot); + } - if (!itemstack2.isEmpty()) { - if (itemstack1.isEmpty()) { - inventoryCrafting.setItem(i, itemstack2); - } else if (net.minecraft.world.item.ItemStack.isSameItemSameComponents(itemstack1, itemstack2)) { - itemstack2.grow(itemstack1.getCount()); - inventoryCrafting.setItem(i, itemstack2); - } else { - craftItemResult.getOverflowItems().add(CraftItemStack.asBukkitCopy(itemstack2)); + if (!remainingItem.isEmpty()) { + if (itemInMenu.isEmpty()) { + inventoryCrafting.setItem(inventorySlot, remainingItem); + } else if (net.minecraft.world.item.ItemStack.isSameItemSameComponents(itemInMenu, remainingItem)) { + remainingItem.grow(itemInMenu.getCount()); + inventoryCrafting.setItem(inventorySlot, remainingItem); + } else { + craftItemResult.getOverflowItems().add(CraftItemStack.asBukkitCopy(remainingItem)); + } } } } @@ -1861,6 +1872,11 @@ public final class CraftServer implements Server { return this.console.usesAuthentication(); } + @Override + public @NotNull ServerConfiguration getServerConfig() { + return serverConfig; + } + @Override public boolean getAllowFlight() { return this.console.isFlightAllowed(); @@ -2537,7 +2553,7 @@ public final class CraftServer implements Server { completions = this.getCommandMap().tabComplete(player, message, CraftLocation.toBukkit(pos, world.getWorld())); } } catch (CommandException ex) { - player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to tab-complete this command"); + player.sendMessage(Component.text("An internal error occurred while attempting to tab-complete this command", NamedTextColor.RED)); this.getLogger().log(Level.SEVERE, "Exception when " + player.getName() + " attempted to tab complete " + message, ex); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java index e57d62f4e..9c8d305f5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java @@ -14,6 +14,10 @@ public class CraftSound extends OldEnumHolderable implements return CraftRegistry.minecraftToBukkit(minecraft, Registries.SOUND_EVENT); } + public static Sound minecraftHolderToBukkit(Holder minecraft) { + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.SOUND_EVENT); + } + public static SoundEvent bukkitToMinecraft(Sound bukkit) { return CraftRegistry.bukkitToMinecraft(bukkit); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 4a4057440..aae378697 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -157,8 +157,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { private WorldBorder worldBorder; private Environment environment; private final CraftServer server = (CraftServer) Bukkit.getServer(); - private final ChunkGenerator generator; - private final BiomeProvider biomeProvider; + private final @Nullable ChunkGenerator generator; + private final @Nullable BiomeProvider biomeProvider; private final List populators = new ArrayList(); private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this); private final Object2IntOpenHashMap spawnCategoryLimit = new Object2IntOpenHashMap<>(); @@ -286,12 +286,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { private static final Random rand = new Random(); - public CraftWorld(ServerLevel world, ChunkGenerator gen, BiomeProvider biomeProvider, Environment env) { + public CraftWorld(ServerLevel world, @Nullable ChunkGenerator generator, @Nullable BiomeProvider biomeProvider, Environment environment) { this.world = world; - this.generator = gen; + this.generator = generator; this.biomeProvider = biomeProvider; - this.environment = env; + this.environment = environment; // Paper start - per world spawn limits for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { @@ -909,7 +909,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { } @Override - public Environment getEnvironment() { + public @NotNull Environment getEnvironment() { return this.environment; } @@ -924,12 +924,12 @@ public class CraftWorld extends CraftRegionAccessor implements World { } @Override - public ChunkGenerator getGenerator() { + public @Nullable ChunkGenerator getGenerator() { return this.generator; } @Override - public BiomeProvider getBiomeProvider() { + public @Nullable BiomeProvider getBiomeProvider() { return this.biomeProvider; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/paper-server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java index f492098ac..7876e09b9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -26,10 +26,12 @@ import org.bukkit.entity.minecart.CommandMinecart; public class VanillaCommandWrapper extends BukkitCommand { // Paper public final CommandNode vanillaCommand; + public final String helpCommandNamespace; - public VanillaCommandWrapper(String name, String description, String usageMessage, List aliases, CommandNode vanillaCommand) { + public VanillaCommandWrapper(String name, String description, String usageMessage, List aliases, CommandNode vanillaCommand, String helpCommandNamespace) { super(name, description, usageMessage, aliases); this.vanillaCommand = vanillaCommand; + this.helpCommandNamespace = helpCommandNamespace; } Commands commands() { @@ -40,6 +42,7 @@ public class VanillaCommandWrapper extends BukkitCommand { // Paper super(vanillaCommand.getName(), "A Mojang provided command.", vanillaCommand.getUsageText(), Collections.emptyList()); this.vanillaCommand = vanillaCommand; this.setPermission(VanillaCommandWrapper.getPermission(vanillaCommand)); + this.helpCommandNamespace = "Minecraft"; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java index e8d82054d..8244b7eac 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java @@ -9,6 +9,11 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti super(server, entity); } + @Override + public net.minecraft.world.entity.projectile.Projectile getHandle() { + return (net.minecraft.world.entity.projectile.Projectile) this.entity; + } + @Override public boolean doesBounce() { return false; @@ -53,11 +58,6 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle(), new net.minecraft.world.phys.Vec3(vector.getX(), vector.getY(), vector.getZ()))); } - @Override - public net.minecraft.world.entity.projectile.Projectile getHandle() { - return (net.minecraft.world.entity.projectile.Projectile) entity; - } - @Override public final org.bukkit.projectiles.ProjectileSource getShooter() { this.getHandle().refreshProjectileSource(true); // Paper - Refresh ProjectileSource for projectiles diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java index 41dad052d..b8bfb6636 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import java.util.List; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.Items; import net.minecraft.world.level.BlockCollisions; @@ -13,7 +14,6 @@ import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.AbstractArrow; import org.bukkit.inventory.ItemStack; -import java.util.List; public abstract class CraftAbstractArrow extends AbstractProjectile implements AbstractArrow { @@ -21,6 +21,11 @@ public abstract class CraftAbstractArrow extends AbstractProjectile implements A super(server, entity); } + @Override + public net.minecraft.world.entity.projectile.AbstractArrow getHandle() { + return (net.minecraft.world.entity.projectile.AbstractArrow) this.entity; + } + @Override public void setKnockbackStrength(int knockbackStrength) { } @@ -63,8 +68,6 @@ public abstract class CraftAbstractArrow extends AbstractProjectile implements A this.getHandle().setCritArrow(critical); } - // Paper - moved to AbstractProjectile - @Override public boolean isInBlock() { return this.getHandle().isInGround(); @@ -139,16 +142,6 @@ public abstract class CraftAbstractArrow extends AbstractProjectile implements A this.getHandle().firedFromWeapon = CraftItemStack.asNMSCopy(item); } - @Override - public net.minecraft.world.entity.projectile.AbstractArrow getHandle() { - return (net.minecraft.world.entity.projectile.AbstractArrow) this.entity; - } - - @Override - public String toString() { - return "CraftAbstractArrow"; - } - // Paper start @Override public CraftItemStack getItemStack() { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractCow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractCow.java index 32563d9b0..4ee1cc51e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractCow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractCow.java @@ -15,5 +15,4 @@ public abstract class CraftAbstractCow extends CraftAnimals implements AbstractC public net.minecraft.world.entity.animal.AbstractCow getHandle() { return (net.minecraft.world.entity.animal.AbstractCow) this.entity; } - } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java index 31d349d8c..f59fdd04d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java @@ -11,13 +11,13 @@ public abstract class CraftAbstractSkeleton extends CraftMonster implements Abst } @Override - public void setSkeletonType(Skeleton.SkeletonType type) { - throw new UnsupportedOperationException("Not supported."); + public net.minecraft.world.entity.monster.AbstractSkeleton getHandle() { + return (net.minecraft.world.entity.monster.AbstractSkeleton) this.entity; } @Override - public net.minecraft.world.entity.monster.AbstractSkeleton getHandle() { - return (net.minecraft.world.entity.monster.AbstractSkeleton) super.getHandle(); + public void setSkeletonType(Skeleton.SkeletonType type) { + throw new UnsupportedOperationException("Not supported."); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java index fbdde28b3..11a72607c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractVillager.java @@ -25,11 +25,6 @@ public abstract class CraftAbstractVillager extends CraftAgeable implements Craf return this.getHandle(); } - @Override - public String toString() { - return "CraftAbstractVillager"; - } - @Override public Inventory getInventory() { return new CraftInventory(this.getHandle().getInventory()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractWindCharge.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractWindCharge.java index 59df9031e..df1e31c60 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractWindCharge.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractWindCharge.java @@ -9,19 +9,14 @@ public abstract class CraftAbstractWindCharge extends CraftFireball implements A super(server, entity); } - @Override - public void explode() { - this.getHandle().explode(this.getHandle().position()); - this.getHandle().discard(EntityRemoveEvent.Cause.EXPLODE); // SPIGOT-7577 - explode doesn't discard the entity, this happens only in tick and onHitBlock - } - @Override public net.minecraft.world.entity.projectile.windcharge.AbstractWindCharge getHandle() { return (net.minecraft.world.entity.projectile.windcharge.AbstractWindCharge) this.entity; } @Override - public String toString() { - return "CraftAbstractWindCharge"; + public void explode() { + this.getHandle().explode(this.getHandle().position()); + this.getHandle().discard(EntityRemoveEvent.Cause.EXPLODE); // SPIGOT-7577 - explode doesn't discard the entity, this happens only in tick and onHitBlock } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java index 6101339a7..809639b79 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java @@ -9,6 +9,11 @@ public class CraftAgeable extends CraftCreature implements Ageable { super(server, entity); } + @Override + public AgeableMob getHandle() { + return (AgeableMob) this.entity; + } + @Override public int getAge() { return this.getHandle().getAge(); @@ -62,14 +67,4 @@ public class CraftAgeable extends CraftCreature implements Ageable { this.setAge(6000); } } - - @Override - public AgeableMob getHandle() { - return (AgeableMob) this.entity; - } - - @Override - public String toString() { - return "CraftAgeable"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java index c64918175..3c1f25507 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAllay.java @@ -21,11 +21,6 @@ public class CraftAllay extends CraftCreature implements org.bukkit.entity.Allay return (Allay) this.entity; } - @Override - public String toString() { - return "CraftAllay"; - } - @Override public Inventory getInventory() { return new CraftInventory(this.getHandle().getInventory()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java index 2a2f9f090..2cf667d8f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java @@ -13,9 +13,4 @@ public class CraftAmbient extends CraftMob implements Ambient { public AmbientCreature getHandle() { return (AmbientCreature) this.entity; } - - @Override - public String toString() { - return "CraftAmbient"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java index ab42bc721..9bd90d058 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java @@ -20,11 +20,6 @@ public class CraftAnimals extends CraftAgeable implements Animals { return (Animal) this.entity; } - @Override - public String toString() { - return "CraftAnimals"; - } - @Override public UUID getBreedCause() { return this.getHandle().loveCause; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java index 205f5b022..30dea480d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java @@ -30,12 +30,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud @Override public net.minecraft.world.entity.AreaEffectCloud getHandle() { - return (net.minecraft.world.entity.AreaEffectCloud) super.getHandle(); - } - - @Override - public String toString() { - return "CraftAreaEffectCloud"; + return (net.minecraft.world.entity.AreaEffectCloud) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java index e7f2d8de2..2b52654e8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java @@ -1,5 +1,7 @@ package org.bukkit.craftbukkit.entity; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.animal.armadillo.Armadillo.ArmadilloState; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Armadillo; @@ -11,11 +13,46 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo { @Override public net.minecraft.world.entity.animal.armadillo.Armadillo getHandle() { - return (net.minecraft.world.entity.animal.armadillo.Armadillo) super.getHandle(); + return (net.minecraft.world.entity.animal.armadillo.Armadillo) this.entity; } @Override - public String toString() { - return "CraftArmadillo"; + public State getState() { + return CraftArmadillo.stateToBukkit(this.getHandle().getState()); + } + + @Override + public void rollUp() { + this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, net.minecraft.world.entity.animal.armadillo.Armadillo.SCARE_CHECK_INTERVAL); + this.getHandle().rollUp(); + } + + @Override + public void rollOut() { + if (this.getHandle().getBrain().getTimeUntilExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY) <= ArmadilloState.UNROLLING.animationDuration()) { + // already unrolling or unrolled + return; + } + + this.getHandle().lastHurtByMob = null; // Clear this memory to not have the sensor trigger rollUp instantly for damaged armadillo + this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, ArmadilloState.UNROLLING.animationDuration()); + } + + public static State stateToBukkit(ArmadilloState state) { + return switch (state) { + case IDLE -> State.IDLE; + case ROLLING -> State.ROLLING; + case SCARED -> State.SCARED; + case UNROLLING -> State.UNROLLING; + }; + } + + public static ArmadilloState stateToNMS(State state) { + return switch (state) { + case State.IDLE -> ArmadilloState.IDLE; + case State.ROLLING -> ArmadilloState.ROLLING; + case State.SCARED -> ArmadilloState.SCARED; + case State.UNROLLING -> ArmadilloState.UNROLLING; + }; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index 0a51414de..e8371e515 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -15,14 +15,9 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { super(server, entity); } - @Override - public String toString() { - return "CraftArmorStand"; - } - @Override public net.minecraft.world.entity.decoration.ArmorStand getHandle() { - return (net.minecraft.world.entity.decoration.ArmorStand) super.getHandle(); + return (net.minecraft.world.entity.decoration.ArmorStand) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java index 980a042cb..7926dca4e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java @@ -29,11 +29,6 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow { return (net.minecraft.world.entity.projectile.Arrow) this.entity; } - @Override - public String toString() { - return "CraftArrow"; - } - @Override public boolean addCustomEffect(PotionEffect effect, boolean override) { if (this.hasCustomEffect(effect.getType())) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java index 7f9872054..a77124dfb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAxolotl.java @@ -12,12 +12,7 @@ public class CraftAxolotl extends CraftAnimals implements Axolotl, io.papermc.pa @Override public net.minecraft.world.entity.animal.axolotl.Axolotl getHandle() { - return (net.minecraft.world.entity.animal.axolotl.Axolotl) super.getHandle(); - } - - @Override - public String toString() { - return "CraftAxolotl"; + return (net.minecraft.world.entity.animal.axolotl.Axolotl) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java index 8b943de2b..7b29d3127 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java @@ -14,11 +14,6 @@ public class CraftBat extends CraftAmbient implements Bat { return (net.minecraft.world.entity.ambient.Bat) this.entity; } - @Override - public String toString() { - return "CraftBat"; - } - @Override public boolean isAwake() { return !this.getHandle().isResting(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java index bfc2ab243..820564c88 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java @@ -18,11 +18,6 @@ public class CraftBee extends CraftAnimals implements Bee { return (net.minecraft.world.entity.animal.Bee) this.entity; } - @Override - public String toString() { - return "CraftBee"; - } - @Override public Location getHive() { BlockPos hive = this.getHandle().getHivePos(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java index a4c9c7369..afd698a2f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java @@ -12,9 +12,4 @@ public class CraftBlaze extends CraftMonster implements Blaze { public net.minecraft.world.entity.monster.Blaze getHandle() { return (net.minecraft.world.entity.monster.Blaze) this.entity; } - - @Override - public String toString() { - return "CraftBlaze"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockAttachedEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockAttachedEntity.java index 5b0dd9aae..1ccb370e7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockAttachedEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockAttachedEntity.java @@ -12,9 +12,4 @@ public class CraftBlockAttachedEntity extends CraftEntity { public BlockAttachedEntity getHandle() { return (BlockAttachedEntity) this.entity; } - - @Override - public String toString() { - return "CraftBlockAttachedEntity"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockDisplay.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockDisplay.java index dd91de8f2..6502c0622 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockDisplay.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlockDisplay.java @@ -14,12 +14,7 @@ public class CraftBlockDisplay extends CraftDisplay implements BlockDisplay { @Override public net.minecraft.world.entity.Display.BlockDisplay getHandle() { - return (net.minecraft.world.entity.Display.BlockDisplay) super.getHandle(); - } - - @Override - public String toString() { - return "CraftBlockDisplay"; + return (net.minecraft.world.entity.Display.BlockDisplay) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java index 72d736759..aba0a70af 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -1,12 +1,10 @@ package org.bukkit.craftbukkit.entity; -import java.util.stream.Collectors; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.vehicle.AbstractBoat; import org.bukkit.TreeSpecies; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Boat; -import org.bukkit.entity.Entity; public abstract class CraftBoat extends CraftVehicle implements Boat, io.papermc.paper.entity.PaperLeashable { // Paper - Leashable API @@ -14,6 +12,11 @@ public abstract class CraftBoat extends CraftVehicle implements Boat, io.papermc super(server, entity); } + @Override + public AbstractBoat getHandle() { + return (AbstractBoat) this.entity; + } + @Override public TreeSpecies getWoodType() { return CraftBoat.getTreeSpecies(this.getHandle().getType()); @@ -99,16 +102,6 @@ public abstract class CraftBoat extends CraftVehicle implements Boat, io.papermc return CraftBoat.boatStatusFromNms(this.getHandle().status); } - @Override - public AbstractBoat getHandle() { - return (AbstractBoat) this.entity; - } - - @Override - public String toString() { - return "CraftBoat{boatType=" + this.getBoatType() + ",status=" + this.getStatus() + ",passengers=" + this.getPassengers().stream().map(Entity::toString).collect(Collectors.joining("-", "{", "}")) + "}"; - } - public static Boat.Type boatTypeFromNms(EntityType boatType) { if (boatType == EntityType.OAK_BOAT || boatType == EntityType.OAK_CHEST_BOAT) { return Type.OAK; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java index e8e470430..3db0be03f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBogged.java @@ -15,11 +15,6 @@ public class CraftBogged extends CraftAbstractSkeleton implements Bogged, io.pap return (net.minecraft.world.entity.monster.Bogged) this.entity; } - @Override - public String toString() { - return "CraftBogged"; - } - @Override public Skeleton.SkeletonType getSkeletonType() { return Skeleton.SkeletonType.BOGGED; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreeze.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreeze.java index 7648e2c70..f71864abb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreeze.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreeze.java @@ -22,9 +22,4 @@ public class CraftBreeze extends CraftMonster implements Breeze { net.minecraft.world.entity.LivingEntity entityLivingTarget = (target instanceof CraftLivingEntity craftLivingEntity) ? craftLivingEntity.getHandle() : null; this.getHandle().getBrain().setMemory(MemoryModuleType.ATTACK_TARGET, entityLivingTarget); // SPIGOT-7957: We need override memory for set target and trigger attack behaviours } - - @Override - public String toString() { - return "CraftBreeze"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreezeWindCharge.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreezeWindCharge.java index e88e52a9b..59dd96368 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreezeWindCharge.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftBreezeWindCharge.java @@ -12,9 +12,4 @@ public class CraftBreezeWindCharge extends CraftAbstractWindCharge implements Br public net.minecraft.world.entity.projectile.windcharge.BreezeWindCharge getHandle() { return (net.minecraft.world.entity.projectile.windcharge.BreezeWindCharge) this.entity; } - - @Override - public String toString() { - return "CraftBreezeWindCharge"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCamel.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCamel.java index 80e571c97..93d7fde68 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCamel.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCamel.java @@ -13,12 +13,7 @@ public class CraftCamel extends CraftAbstractHorse implements Camel { @Override public net.minecraft.world.entity.animal.camel.Camel getHandle() { - return (net.minecraft.world.entity.animal.camel.Camel) super.getHandle(); - } - - @Override - public String toString() { - return "CraftCamel"; + return (net.minecraft.world.entity.animal.camel.Camel) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java index 70619f6cd..602659747 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java @@ -20,12 +20,7 @@ public class CraftCat extends CraftTameableAnimal implements Cat { @Override public net.minecraft.world.entity.animal.Cat getHandle() { - return (net.minecraft.world.entity.animal.Cat) super.getHandle(); - } - - @Override - public String toString() { - return "CraftCat"; + return (net.minecraft.world.entity.animal.Cat) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java index 4f661fbdb..79907f902 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java @@ -12,9 +12,4 @@ public class CraftCaveSpider extends CraftSpider implements CaveSpider { public net.minecraft.world.entity.monster.CaveSpider getHandle() { return (net.minecraft.world.entity.monster.CaveSpider) this.entity; } - - @Override - public String toString() { - return "CraftCaveSpider"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java index 8a022e2c1..22ea11d7a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java @@ -18,11 +18,6 @@ public abstract class CraftChestBoat extends CraftBoat implements org.bukkit.ent return (AbstractChestBoat) this.entity; } - @Override - public String toString() { - return "CraftChestBoat"; - } - @Override public Inventory getInventory() { return this.inventory; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestedHorse.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestedHorse.java index 40ee96e31..d05897695 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestedHorse.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChestedHorse.java @@ -12,7 +12,7 @@ public abstract class CraftChestedHorse extends CraftAbstractHorse implements Ch @Override public AbstractChestedHorse getHandle() { - return (AbstractChestedHorse) super.getHandle(); + return (AbstractChestedHorse) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java index 9210c84bb..ec6e42a61 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java @@ -22,11 +22,6 @@ public class CraftChicken extends CraftAnimals implements Chicken { return (net.minecraft.world.entity.animal.Chicken) this.entity; } - @Override - public String toString() { - return "CraftChicken"; - } - @Override public Variant getVariant() { return CraftVariant.minecraftHolderToBukkit(this.getHandle().getVariant()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCod.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCod.java index 63e6b07e3..ca8c10cca 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCod.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCod.java @@ -11,11 +11,6 @@ public class CraftCod extends io.papermc.paper.entity.PaperSchoolableFish implem @Override public net.minecraft.world.entity.animal.Cod getHandle() { - return (net.minecraft.world.entity.animal.Cod) super.getHandle(); - } - - @Override - public String toString() { - return "CraftCod"; + return (net.minecraft.world.entity.animal.Cod) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java index c2583982d..178cadf02 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java @@ -1,20 +1,25 @@ package org.bukkit.craftbukkit.entity; import net.minecraft.world.entity.boss.EnderDragonPart; -import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.ComplexEntityPart; import org.bukkit.entity.ComplexLivingEntity; import org.bukkit.event.entity.EntityDamageEvent; public class CraftComplexPart extends CraftEntity implements ComplexEntityPart { + public CraftComplexPart(CraftServer server, EnderDragonPart entity) { super(server, entity); } + @Override + public EnderDragonPart getHandle() { + return (EnderDragonPart) this.entity; + } + @Override public ComplexLivingEntity getParent() { - return (ComplexLivingEntity) ((EnderDragon) this.getHandle().parentMob).getBukkitEntity(); + return (ComplexLivingEntity) this.getHandle().parentMob.getBukkitEntity(); } @Override @@ -31,14 +36,4 @@ public class CraftComplexPart extends CraftEntity implements ComplexEntityPart { public boolean isValid() { return this.getParent().isValid(); } - - @Override - public EnderDragonPart getHandle() { - return (EnderDragonPart) this.entity; - } - - @Override - public String toString() { - return "CraftComplexPart"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java index faf6f6204..d21aa1b8b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java @@ -22,11 +22,6 @@ public class CraftCow extends CraftAbstractCow implements Cow { return (net.minecraft.world.entity.animal.Cow) this.entity; } - @Override - public String toString() { - return "CraftCow"; - } - @Override public Variant getVariant() { return CraftVariant.minecraftHolderToBukkit(this.getHandle().getVariant()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreaking.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreaking.java index d9b7ad7f3..ebdf5c7df 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreaking.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreaking.java @@ -43,9 +43,4 @@ public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Cre public boolean isActive() { return this.getHandle().isActive(); } - - @Override - public String toString() { - return "CraftCreaking"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java index 664d9c179..c99c1d36e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java @@ -13,9 +13,4 @@ public class CraftCreature extends CraftMob implements Creature { public PathfinderMob getHandle() { return (PathfinderMob) this.entity; } - - @Override - public String toString() { - return "CraftCreature"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java index 42dd26b91..2fa2811c3 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java @@ -12,6 +12,11 @@ public class CraftCreeper extends CraftMonster implements Creeper { super(server, entity); } + @Override + public net.minecraft.world.entity.monster.Creeper getHandle() { + return (net.minecraft.world.entity.monster.Creeper) this.entity; + } + @Override public boolean isPowered() { return this.getHandle().isPowered(); @@ -92,16 +97,6 @@ public class CraftCreeper extends CraftMonster implements Creeper { return (this.getHandle().entityIgniter != null) ? this.getHandle().entityIgniter.getBukkitEntity() : null; } - @Override - public net.minecraft.world.entity.monster.Creeper getHandle() { - return (net.minecraft.world.entity.monster.Creeper) this.entity; - } - - @Override - public String toString() { - return "CraftCreeper"; - } - // Paper start @Override public void setIgnited(boolean ignited) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java index 48eeb1d9b..90dcaf8e6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDisplay.java @@ -14,12 +14,7 @@ public class CraftDisplay extends CraftEntity implements Display { @Override public net.minecraft.world.entity.Display getHandle() { - return (net.minecraft.world.entity.Display) super.getHandle(); - } - - @Override - public String toString() { - return "CraftDisplay"; + return (net.minecraft.world.entity.Display) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java index 7222365af..0400e181e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java @@ -13,12 +13,7 @@ public class CraftDolphin extends CraftAgeable implements Dolphin { @Override public net.minecraft.world.entity.animal.Dolphin getHandle() { - return (net.minecraft.world.entity.animal.Dolphin) super.getHandle(); - } - - @Override - public String toString() { - return "CraftDolphin"; + return (net.minecraft.world.entity.animal.Dolphin) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDonkey.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDonkey.java index 955a1c92a..85820f25d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDonkey.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDonkey.java @@ -10,11 +10,6 @@ public class CraftDonkey extends CraftChestedHorse implements Donkey { super(server, entity); } - @Override - public String toString() { - return "CraftDonkey"; - } - @Override public Variant getVariant() { return Variant.DONKEY; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDragonFireball.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDragonFireball.java index b884c6b08..00b4487b1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDragonFireball.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDragonFireball.java @@ -4,12 +4,8 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.DragonFireball; public class CraftDragonFireball extends CraftFireball implements DragonFireball { + public CraftDragonFireball(CraftServer server, net.minecraft.world.entity.projectile.DragonFireball entity) { super(server, entity); } - - @Override - public String toString() { - return "CraftDragonFireball"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java index 51fc4acae..4dfed6e60 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java @@ -13,9 +13,4 @@ public class CraftDrowned extends CraftZombie implements Drowned, com.destroysto public net.minecraft.world.entity.monster.Drowned getHandle() { return (net.minecraft.world.entity.monster.Drowned) this.entity; } - - @Override - public String toString() { - return "CraftDrowned"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java index 010e9e922..6b1c6e023 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java @@ -5,6 +5,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Egg; public class CraftEgg extends CraftThrowableProjectile implements Egg { + public CraftEgg(CraftServer server, ThrownEgg entity) { super(server, entity); } @@ -13,9 +14,4 @@ public class CraftEgg extends CraftThrowableProjectile implements Egg { public ThrownEgg getHandle() { return (ThrownEgg) this.entity; } - - @Override - public String toString() { - return "CraftEgg"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftElderGuardian.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftElderGuardian.java index 0e5d7ba2a..7cd75b7ea 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftElderGuardian.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftElderGuardian.java @@ -9,11 +9,6 @@ public class CraftElderGuardian extends CraftGuardian implements ElderGuardian { super(server, entity); } - @Override - public String toString() { - return "CraftElderGuardian"; - } - @Override public boolean isElder() { return true; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java index 8ebd824e7..2229a03fd 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java @@ -8,10 +8,16 @@ import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.entity.EnderCrystal; public class CraftEnderCrystal extends CraftEntity implements EnderCrystal { + public CraftEnderCrystal(CraftServer server, EndCrystal entity) { super(server, entity); } + @Override + public EndCrystal getHandle() { + return (EndCrystal) this.entity; + } + @Override public boolean isShowingBottom() { return this.getHandle().showsBottom(); @@ -38,14 +44,4 @@ public class CraftEnderCrystal extends CraftEntity implements EnderCrystal { this.getHandle().setBeamTarget(CraftLocation.toBlockPosition(location)); } } - - @Override - public EndCrystal getHandle() { - return (EndCrystal) this.entity; - } - - @Override - public String toString() { - return "CraftEnderCrystal"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java index 82b28b2e8..a716433db 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java @@ -20,6 +20,11 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem super(server, entity); } + @Override + public net.minecraft.world.entity.boss.enderdragon.EnderDragon getHandle() { + return (net.minecraft.world.entity.boss.enderdragon.EnderDragon) this.entity; + } + @Override public Set getParts() { Builder builder = ImmutableSet.builder(); @@ -31,16 +36,6 @@ public class CraftEnderDragon extends CraftMob implements EnderDragon, CraftEnem return builder.build(); } - @Override - public net.minecraft.world.entity.boss.enderdragon.EnderDragon getHandle() { - return (net.minecraft.world.entity.boss.enderdragon.EnderDragon) this.entity; - } - - @Override - public String toString() { - return "CraftEnderDragon"; - } - @Override public Phase getPhase() { return Phase.values()[this.getHandle().getEntityData().get(net.minecraft.world.entity.boss.enderdragon.EnderDragon.DATA_PHASE)]; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java index 05a6fc957..9d7268b6b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java @@ -16,16 +16,6 @@ public class CraftEnderDragonPart extends CraftComplexPart implements EnderDrago return (EnderDragon) super.getParent(); } - @Override - public net.minecraft.world.entity.boss.EnderDragonPart getHandle() { - return (net.minecraft.world.entity.boss.EnderDragonPart) this.entity; - } - - @Override - public String toString() { - return "CraftEnderDragonPart"; - } - @Override public void damage(double amount, DamageSource damageSource) { this.getParent().damage(amount, damageSource); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java index 3bb8d74f2..eb7e63d56 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java @@ -13,9 +13,4 @@ public class CraftEnderPearl extends CraftThrowableProjectile implements EnderPe public ThrownEnderpearl getHandle() { return (ThrownEnderpearl) this.entity; } - - @Override - public String toString() { - return "CraftEnderPearl"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java index 27f56fa4b..7feea819b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java @@ -20,11 +20,6 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal { return (EyeOfEnder) this.entity; } - @Override - public String toString() { - return "CraftEnderSignal"; - } - @Override public Location getTargetLocation() { return new Location(this.getWorld(), this.getHandle().tx, this.getHandle().ty, this.getHandle().tz, this.getHandle().getYRot(), this.getHandle().getXRot()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java index 59195000e..52a5240b7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java @@ -13,11 +13,21 @@ import org.bukkit.entity.Entity; import org.bukkit.material.MaterialData; public class CraftEnderman extends CraftMonster implements Enderman { + public CraftEnderman(CraftServer server, EnderMan entity) { super(server, entity); } - @Override public boolean teleportRandomly() { return getHandle().teleport(); } // Paper + @Override + public EnderMan getHandle() { + return (EnderMan) this.entity; + } + + @Override + public boolean teleportRandomly() { + return getHandle().teleport(); + } + @Override public MaterialData getCarriedMaterial() { BlockState blockData = this.getHandle().getCarriedBlock(); @@ -60,16 +70,6 @@ public class CraftEnderman extends CraftMonster implements Enderman { this.getHandle().setHasBeenStaredAt(hasBeenStaredAt); } - @Override - public EnderMan getHandle() { - return (EnderMan) this.entity; - } - - @Override - public String toString() { - return "CraftEnderman"; - } - @Override public boolean teleport() { return this.getHandle().teleport(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java index 4d5958405..000c5ea5d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java @@ -11,12 +11,7 @@ public class CraftEndermite extends CraftMonster implements Endermite { @Override public net.minecraft.world.entity.monster.Endermite getHandle() { - return (net.minecraft.world.entity.monster.Endermite) super.getHandle(); - } - - @Override - public String toString() { - return "CraftEndermite"; + return (net.minecraft.world.entity.monster.Endermite) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index c8caeba77..3b41a37f8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -13,6 +13,7 @@ import java.util.Set; import java.util.UUID; import io.papermc.paper.entity.LookAnchor; import java.util.concurrent.CompletableFuture; +import net.kyori.adventure.util.TriState; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; @@ -57,6 +58,7 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.MetadataValue; import org.bukkit.permissions.PermissibleBase; import org.bukkit.permissions.Permission; @@ -124,6 +126,38 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { throw new AssertionError("Unknown entity " + (entity == null ? null : entity.getClass())); } + public Entity getHandle() { + return this.entity; + } + + public Entity getHandleRaw() { + return this.entity; + } + + public void setHandle(final Entity entity) { + this.entity = entity; + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "{uuid=" + this.getUniqueId() + '}'; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + final CraftEntity other = (CraftEntity) obj; + return this.entity == other.entity; // There should never be duplicate entities with differing references + } + + @Override + public int hashCode() { + // The UUID and thus hash code should never change (unlike the entity id) + return this.getUniqueId().hashCode(); + } + @Override public Location getLocation() { return CraftLocation.toBukkit(this.entity.position(), this.getWorld(), this.entity.getBukkitYaw(), this.entity.getXRot()); @@ -363,13 +397,25 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } @Override + @Deprecated public void setVisualFire(boolean fire) { - this.getHandle().hasVisualFire = fire; + setVisualFire(fire ? TriState.TRUE : TriState.NOT_SET); + } + + @Override + public void setVisualFire(final TriState fire) { + Preconditions.checkArgument(fire != null, "TriState cannot be null"); + this.getHandle().visualFire = fire; } @Override public boolean isVisualFire() { - return this.getHandle().hasVisualFire; + return getVisualFire().toBooleanOrElse(false); + } + + @Override + public TriState getVisualFire() { + return this.getHandle().visualFire; } @Override @@ -487,6 +533,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return true; } + @Override + public ItemStack getPickItemStack() { + net.minecraft.world.item.ItemStack stack = this.getHandle().getPickResult(); + return stack == null ? ItemStack.empty() : stack.asBukkitCopy(); + } + @Override public float getFallDistance() { return (float) this.getHandle().fallDistance; @@ -524,14 +576,6 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { this.getHandle().totalEntityAge = value; } - public Entity getHandle() { - return this.entity; - } - - public Entity getHandleRaw() { - return this.entity; - } - @Override public final EntityType getType() { return this.entityType; @@ -561,30 +605,6 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return CraftSound.minecraftToBukkit(this.getHandle().getSwimHighSpeedSplashSound()); } - public void setHandle(final Entity entity) { - this.entity = entity; - } - - @Override - public String toString() { - return "CraftEntity{" + "id=" + this.getEntityId() + '}'; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - final CraftEntity other = (CraftEntity) obj; - return this.entity == other.entity; // There should never be duplicate entities with differing references - } - - @Override - public int hashCode() { - // The UUID and thus hash code should never change (unlike the entity id) - return this.getUniqueId().hashCode(); - } - @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { this.server.getEntityMetadata().setMetadata(this, metadataKey, newMetadataValue); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java index 64efbf845..73b501367 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvoker.java @@ -13,12 +13,7 @@ public class CraftEvoker extends CraftSpellcaster implements Evoker { @Override public net.minecraft.world.entity.monster.Evoker getHandle() { - return (net.minecraft.world.entity.monster.Evoker) super.getHandle(); - } - - @Override - public String toString() { - return "CraftEvoker"; + return (net.minecraft.world.entity.monster.Evoker) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvokerFangs.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvokerFangs.java index 19b368cc8..5bf6f079a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvokerFangs.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEvokerFangs.java @@ -13,12 +13,7 @@ public class CraftEvokerFangs extends CraftEntity implements EvokerFangs { @Override public net.minecraft.world.entity.projectile.EvokerFangs getHandle() { - return (net.minecraft.world.entity.projectile.EvokerFangs) super.getHandle(); - } - - @Override - public String toString() { - return "CraftEvokerFangs"; + return (net.minecraft.world.entity.projectile.EvokerFangs) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java index a3dfa081f..8cd7ba2f4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java @@ -5,10 +5,16 @@ import org.bukkit.entity.ExperienceOrb; import java.util.UUID; public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb { + public CraftExperienceOrb(CraftServer server, net.minecraft.world.entity.ExperienceOrb entity) { super(server, entity); } + @Override + public net.minecraft.world.entity.ExperienceOrb getHandle() { + return (net.minecraft.world.entity.ExperienceOrb) this.entity; + } + @Override public int getExperience() { return this.getHandle().getValue(); @@ -43,14 +49,4 @@ public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb { public SpawnReason getSpawnReason() { return this.getHandle().spawnReason; } - - @Override - public net.minecraft.world.entity.ExperienceOrb getHandle() { - return (net.minecraft.world.entity.ExperienceOrb) this.entity; - } - - @Override - public String toString() { - return "CraftExperienceOrb"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java index 93a33c9ce..eacdc2467 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingBlock.java @@ -19,11 +19,6 @@ public class CraftFallingBlock extends CraftEntity implements FallingBlock { return (FallingBlockEntity) this.entity; } - @Override - public String toString() { - return "CraftFallingBlock"; - } - @Override public Material getMaterial() { return this.getBlockData().getMaterial(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java index 74190127e..7e53e12c8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java @@ -9,10 +9,16 @@ import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; public class CraftFireball extends AbstractProjectile implements Fireball { + public CraftFireball(CraftServer server, AbstractHurtingProjectile entity) { super(server, entity); } + @Override + public AbstractHurtingProjectile getHandle() { + return (AbstractHurtingProjectile) this.entity; + } + @Override public float getYield() { return this.getHandle().bukkitYield; @@ -78,14 +84,4 @@ public class CraftFireball extends AbstractProjectile implements Fireball { return this.getAcceleration(); } // Paper end - Expose power on fireball projectiles - - @Override - public AbstractHurtingProjectile getHandle() { - return (AbstractHurtingProjectile) this.entity; - } - - @Override - public String toString() { - return "CraftFireball"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java index a9ffd363b..c64e78d54 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java @@ -23,11 +23,6 @@ public class CraftFirework extends CraftProjectile implements Firework { return (FireworkRocketEntity) this.entity; } - @Override - public String toString() { - return "CraftFirework"; - } - @Override public FireworkMeta getFireworkMeta() { return (FireworkMeta) CraftItemStack.getItemMeta(this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM), org.bukkit.inventory.ItemType.FIREWORK_ROCKET); // Paper - Expose firework item directly diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java index eb10f94d5..207f06a85 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java @@ -14,9 +14,4 @@ public class CraftFish extends CraftWaterMob implements Fish, io.papermc.paper.e public AbstractFish getHandle() { return (AbstractFish) this.entity; } - - @Override - public String toString() { - return "CraftFish"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java index 5f7225f18..327a686a2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java @@ -14,6 +14,7 @@ import org.bukkit.entity.FishHook; import org.bukkit.inventory.EquipmentSlot; public class CraftFishHook extends CraftProjectile implements FishHook { + private double biteChance = -1; public CraftFishHook(CraftServer server, FishingHook entity) { @@ -25,11 +26,6 @@ public class CraftFishHook extends CraftProjectile implements FishHook { return (FishingHook) this.entity; } - @Override - public String toString() { - return "CraftFishingHook"; - } - @Override public int getMinWaitTime() { return this.getHandle().minWaitTime; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java index 8117faa0c..974ed7be3 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java @@ -14,9 +14,4 @@ public class CraftFlying extends CraftMob implements Flying { public FlyingMob getHandle() { return (FlyingMob) this.entity; } - - @Override - public String toString() { - return "CraftFlying"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java index 0aefbba2d..8084bd678 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java @@ -17,12 +17,7 @@ public class CraftFox extends CraftAnimals implements Fox { @Override public net.minecraft.world.entity.animal.Fox getHandle() { - return (net.minecraft.world.entity.animal.Fox) super.getHandle(); - } - - @Override - public String toString() { - return "CraftFox"; + return (net.minecraft.world.entity.animal.Fox) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java index d8c28fb3c..f4de532f2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFrog.java @@ -23,11 +23,6 @@ public class CraftFrog extends CraftAnimals implements org.bukkit.entity.Frog { return (Frog) this.entity; } - @Override - public String toString() { - return "CraftFrog"; - } - @Override public Entity getTongueTarget() { return this.getHandle().getTongueTarget().map(net.minecraft.world.entity.Entity::getBukkitEntity).orElse(null); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java index 692b35b25..7ae83ee68 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java @@ -14,11 +14,6 @@ public class CraftGhast extends CraftFlying implements Ghast, CraftEnemy { return (net.minecraft.world.entity.monster.Ghast) this.entity; } - @Override - public String toString() { - return "CraftGhast"; - } - @Override public boolean isCharging() { return this.getHandle().isCharging(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java index 582620533..84c1dc9bc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java @@ -13,9 +13,4 @@ public class CraftGiant extends CraftMonster implements Giant { public net.minecraft.world.entity.monster.Giant getHandle() { return (net.minecraft.world.entity.monster.Giant) this.entity; } - - @Override - public String toString() { - return "CraftGiant"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowItemFrame.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowItemFrame.java index b9a7576d2..b41bd0515 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowItemFrame.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowItemFrame.java @@ -11,11 +11,6 @@ public class CraftGlowItemFrame extends CraftItemFrame implements GlowItemFrame @Override public net.minecraft.world.entity.decoration.GlowItemFrame getHandle() { - return (net.minecraft.world.entity.decoration.GlowItemFrame) super.getHandle(); - } - - @Override - public String toString() { - return "CraftGlowItemFrame{item=" + this.getItem() + ", rotation=" + this.getRotation() + "}"; + return (net.minecraft.world.entity.decoration.GlowItemFrame) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowSquid.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowSquid.java index 253a0d2f9..dac2ac14a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowSquid.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGlowSquid.java @@ -12,12 +12,7 @@ public class CraftGlowSquid extends CraftSquid implements GlowSquid { @Override public net.minecraft.world.entity.GlowSquid getHandle() { - return (net.minecraft.world.entity.GlowSquid) super.getHandle(); - } - - @Override - public String toString() { - return "CraftGlowSquid"; + return (net.minecraft.world.entity.GlowSquid) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java index d4f3370e2..1fcab60ca 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGoat.java @@ -11,12 +11,7 @@ public class CraftGoat extends CraftAnimals implements Goat { @Override public net.minecraft.world.entity.animal.goat.Goat getHandle() { - return (net.minecraft.world.entity.animal.goat.Goat) super.getHandle(); - } - - @Override - public String toString() { - return "CraftGoat"; + return (net.minecraft.world.entity.animal.goat.Goat) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java index e27e46989..9cb3dd093 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java @@ -5,6 +5,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Golem; public class CraftGolem extends CraftCreature implements Golem { + public CraftGolem(CraftServer server, AbstractGolem entity) { super(server, entity); } @@ -13,9 +14,4 @@ public class CraftGolem extends CraftCreature implements Golem { public AbstractGolem getHandle() { return (AbstractGolem) this.entity; } - - @Override - public String toString() { - return "CraftGolem"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java index e232350f2..2f68d8708 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java @@ -15,12 +15,7 @@ public class CraftGuardian extends CraftMonster implements Guardian { @Override public net.minecraft.world.entity.monster.Guardian getHandle() { - return (net.minecraft.world.entity.monster.Guardian) super.getHandle(); - } - - @Override - public String toString() { - return "CraftGuardian"; + return (net.minecraft.world.entity.monster.Guardian) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java index f1e3f2b89..49f5d3113 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java @@ -8,6 +8,7 @@ import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.entity.Hanging; public class CraftHanging extends CraftBlockAttachedEntity implements Hanging { + public CraftHanging(CraftServer server, HangingEntity entity) { super(server, entity); } @@ -61,9 +62,4 @@ public class CraftHanging extends CraftBlockAttachedEntity implements Hanging { public HangingEntity getHandle() { return (HangingEntity) this.entity; } - - @Override - public String toString() { - return "CraftHanging"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHoglin.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHoglin.java index 37007775d..956557239 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHoglin.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHoglin.java @@ -10,6 +10,11 @@ public class CraftHoglin extends CraftAnimals implements Hoglin, CraftEnemy { super(server, entity); } + @Override + public net.minecraft.world.entity.monster.hoglin.Hoglin getHandle() { + return (net.minecraft.world.entity.monster.hoglin.Hoglin) this.entity; + } + @Override public boolean isImmuneToZombification() { return this.getHandle().isImmuneToZombification(); @@ -50,14 +55,4 @@ public class CraftHoglin extends CraftAnimals implements Hoglin, CraftEnemy { public boolean isConverting() { return this.getHandle().isConverting(); } - - @Override - public net.minecraft.world.entity.monster.hoglin.Hoglin getHandle() { - return (net.minecraft.world.entity.monster.hoglin.Hoglin) this.entity; - } - - @Override - public String toString() { - return "CraftHoglin"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java index 045e2ac4f..ef8073dfd 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java @@ -16,7 +16,7 @@ public class CraftHorse extends CraftAbstractHorse implements Horse { @Override public net.minecraft.world.entity.animal.horse.Horse getHandle() { - return (net.minecraft.world.entity.animal.horse.Horse) super.getHandle(); + return (net.minecraft.world.entity.animal.horse.Horse) this.entity; } @Override @@ -63,9 +63,4 @@ public class CraftHorse extends CraftAbstractHorse implements Horse { this.getHandle().createEquipmentSlotContainer(EquipmentSlot.SADDLE) ); } - - @Override - public String toString() { - return "CraftHorse{variant=" + this.getVariant() + ", owner=" + this.getOwner() + '}'; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index 6ad1c2220..934eb5c66 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -80,6 +80,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + private CraftInventoryPlayer inventory; private final CraftInventory enderChest; protected final PermissibleBase perm = new PermissibleBase(this); @@ -93,6 +94,21 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { this.enderChest = new CraftInventory(entity.getEnderChestInventory()); } + @Override + public Player getHandle() { + return (Player) this.entity; + } + + public void setHandle(final Player entity) { + super.setHandle(entity); + this.inventory = new CraftInventoryPlayer(entity.getInventory()); + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + "{name=" + this.getName() + ", uuid=" + this.getUniqueId() + '}'; + } + @Override public PlayerInventory getInventory() { return this.inventory; @@ -304,21 +320,6 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { this.mode = mode; } - @Override - public Player getHandle() { - return (Player) this.entity; - } - - public void setHandle(final Player entity) { - super.setHandle(entity); - this.inventory = new CraftInventoryPlayer(entity.getInventory()); - } - - @Override - public String toString() { - return "CraftHumanEntity{" + "id=" + this.getEntityId() + "name=" + this.getName() + '}'; - } - @Override public InventoryView getOpenInventory() { return this.getHandle().containerMenu.getBukkitView(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHusk.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHusk.java index 4822c744c..43be61235 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHusk.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHusk.java @@ -8,9 +8,4 @@ public class CraftHusk extends CraftZombie implements Husk { public CraftHusk(CraftServer server, net.minecraft.world.entity.monster.Husk entity) { super(server, entity); } - - @Override - public String toString() { - return "CraftHusk"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java index fb3c518f0..fdc42e00b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllager.java @@ -12,11 +12,6 @@ public class CraftIllager extends CraftRaider implements Illager { @Override public AbstractIllager getHandle() { - return (AbstractIllager) super.getHandle(); - } - - @Override - public String toString() { - return "CraftIllager"; + return (AbstractIllager) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java index 5b2af80e5..ed158e3a1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java @@ -11,11 +11,6 @@ public class CraftIllusioner extends CraftSpellcaster implements Illusioner, com @Override public net.minecraft.world.entity.monster.Illusioner getHandle() { - return (net.minecraft.world.entity.monster.Illusioner) super.getHandle(); - } - - @Override - public String toString() { - return "CraftIllusioner"; + return (net.minecraft.world.entity.monster.Illusioner) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftInteraction.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftInteraction.java index caa3016bf..c4f2be2c4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftInteraction.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftInteraction.java @@ -14,12 +14,7 @@ public class CraftInteraction extends CraftEntity implements Interaction { @Override public net.minecraft.world.entity.Interaction getHandle() { - return (net.minecraft.world.entity.Interaction) super.getHandle(); - } - - @Override - public String toString() { - return "CraftInteraction"; + return (net.minecraft.world.entity.Interaction) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java index 63cae1a2e..2d7be6f2a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java @@ -13,11 +13,6 @@ public class CraftIronGolem extends CraftGolem implements IronGolem { return (net.minecraft.world.entity.animal.IronGolem) this.entity; } - @Override - public String toString() { - return "CraftIronGolem"; - } - @Override public boolean isPlayerCreated() { return this.getHandle().isPlayerCreated(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java index cef51ad02..ca656d97a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -143,9 +143,4 @@ public class CraftItem extends CraftEntity implements Item { public UUID getThrower() { return this.getHandle().thrower; } - - @Override - public String toString() { - return "CraftItem"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemDisplay.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemDisplay.java index 787f91566..41c3e5182 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemDisplay.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemDisplay.java @@ -15,12 +15,7 @@ public class CraftItemDisplay extends CraftDisplay implements ItemDisplay { @Override public net.minecraft.world.entity.Display.ItemDisplay getHandle() { - return (net.minecraft.world.entity.Display.ItemDisplay) super.getHandle(); - } - - @Override - public String toString() { - return "CraftItemDisplay"; + return (net.minecraft.world.entity.Display.ItemDisplay) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java index 981527d4a..31aa6d0c2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java @@ -12,10 +12,16 @@ import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.ItemFrame; public class CraftItemFrame extends CraftHanging implements ItemFrame { + public CraftItemFrame(CraftServer server, net.minecraft.world.entity.decoration.ItemFrame entity) { super(server, entity); } + @Override + public net.minecraft.world.entity.decoration.ItemFrame getHandle() { + return (net.minecraft.world.entity.decoration.ItemFrame) this.entity; + } + @Override public boolean setFacingDirection(BlockFace face, boolean force) { HangingEntity hanging = this.getHandle(); @@ -150,14 +156,4 @@ public class CraftItemFrame extends CraftHanging implements ItemFrame { public void setFixed(boolean fixed) { this.getHandle().fixed = fixed; } - - @Override - public net.minecraft.world.entity.decoration.ItemFrame getHandle() { - return (net.minecraft.world.entity.decoration.ItemFrame) this.entity; - } - - @Override - public String toString() { - return "CraftItemFrame{item=" + this.getItem() + ", rotation=" + this.getRotation() + "}"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java index 0848963e6..742c02279 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java @@ -4,23 +4,19 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.LargeFireball; public class CraftLargeFireball extends CraftSizedFireball implements LargeFireball { + public CraftLargeFireball(CraftServer server, net.minecraft.world.entity.projectile.LargeFireball entity) { super(server, entity); } - @Override - public void setYield(float yield) { - super.setYield(yield); - this.getHandle().explosionPower = (int) yield; - } - @Override public net.minecraft.world.entity.projectile.LargeFireball getHandle() { return (net.minecraft.world.entity.projectile.LargeFireball) this.entity; } @Override - public String toString() { - return "CraftLargeFireball"; + public void setYield(float yield) { + super.setYield(yield); + this.getHandle().explosionPower = (int) yield; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java index 76a7fc3d6..902266123 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java @@ -7,10 +7,16 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.LeashHitch; public class CraftLeash extends CraftBlockAttachedEntity implements LeashHitch { + public CraftLeash(CraftServer server, LeashFenceKnotEntity entity) { super(server, entity); } + @Override + public LeashFenceKnotEntity getHandle() { + return (LeashFenceKnotEntity) this.entity; + } + @Override public boolean setFacingDirection(BlockFace face, boolean force) { Preconditions.checkArgument(face == BlockFace.SELF, "%s is not a valid facing direction", face); @@ -34,14 +40,4 @@ public class CraftLeash extends CraftBlockAttachedEntity implements LeashHitch { public void setFacingDirection(BlockFace face) { // Leash hitch has no facing direction } - - @Override - public LeashFenceKnotEntity getHandle() { - return (LeashFenceKnotEntity) this.entity; - } - - @Override - public String toString() { - return "CraftLeash"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java index 533e16e30..32e426513 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java @@ -7,10 +7,16 @@ import org.bukkit.entity.LightningStrike; import org.bukkit.entity.Player; public class CraftLightningStrike extends CraftEntity implements LightningStrike { + public CraftLightningStrike(final CraftServer server, final LightningBolt entity) { super(server, entity); } + @Override + public LightningBolt getHandle() { + return (LightningBolt) this.entity; + } + @Override public boolean isEffect() { return this.getHandle().isEffect; // Paper - Properly handle lightning effects api @@ -41,16 +47,6 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike this.getHandle().setCause((player != null) ? ((CraftPlayer) player).getHandle() : null); } - @Override - public LightningBolt getHandle() { - return (LightningBolt) this.entity; - } - - @Override - public String toString() { - return "CraftLightningStrike"; - } - // Spigot start private final LightningStrike.Spigot spigot = new LightningStrike.Spigot() { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java index bd39ecac8..13feb2f7a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Set; import java.util.UUID; import net.minecraft.Optionull; +import io.papermc.paper.world.damagesource.CombatTracker; import net.minecraft.core.component.DataComponents; import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; import net.minecraft.server.level.ServerLevel; @@ -90,6 +91,7 @@ import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; public class CraftLivingEntity extends CraftEntity implements LivingEntity { + private CraftEntityEquipment equipment; public CraftLivingEntity(final CraftServer server, final net.minecraft.world.entity.LivingEntity entity) { @@ -100,6 +102,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { } } + @Override + public net.minecraft.world.entity.LivingEntity getHandle() { + return (net.minecraft.world.entity.LivingEntity) this.entity; + } + @Override public double getHealth() { return Math.min(Math.max(0, this.getHandle().getHealth()), this.getMaxHealth()); @@ -496,20 +503,6 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { this.getHandle().setNoActionTime(ticks); } - @Override - public net.minecraft.world.entity.LivingEntity getHandle() { - return (net.minecraft.world.entity.LivingEntity) this.entity; - } - - public void setHandle(final net.minecraft.world.entity.LivingEntity entity) { - super.setHandle(entity); - } - - @Override - public String toString() { - return "CraftLivingEntity{" + "id=" + this.getEntityId() + '}'; - } - @Override public Player getKiller() { return Optionull.map(this.getHandle().getLastHurtByPlayer(), player -> (Player) player.getBukkitEntity()); @@ -1167,4 +1160,9 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity { public boolean canUseEquipmentSlot(org.bukkit.inventory.EquipmentSlot slot) { return this.getHandle().canUseSlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)); } + + @Override + public CombatTracker getCombatTracker() { + return this.getHandle().getCombatTracker().paperCombatTracker; + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java index 9aaaf2fc6..02deb9c37 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java @@ -6,7 +6,6 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftInventoryLlama; import org.bukkit.entity.Horse; import org.bukkit.entity.Llama; -import org.bukkit.entity.Llama.Color; import org.bukkit.inventory.LlamaInventory; public class CraftLlama extends CraftChestedHorse implements Llama, com.destroystokyo.paper.entity.CraftRangedEntity { // Paper @@ -17,7 +16,7 @@ public class CraftLlama extends CraftChestedHorse implements Llama, com.destroys @Override public net.minecraft.world.entity.animal.horse.Llama getHandle() { - return (net.minecraft.world.entity.animal.horse.Llama) super.getHandle(); + return (net.minecraft.world.entity.animal.horse.Llama) this.entity; } @Override @@ -58,11 +57,6 @@ public class CraftLlama extends CraftChestedHorse implements Llama, com.destroys return Horse.Variant.LLAMA; } - @Override - public String toString() { - return "CraftLlama"; - } - @Override public boolean inCaravan() { return this.getHandle().inCaravan(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java index 7207c2f06..1425190d5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java @@ -11,11 +11,6 @@ public class CraftLlamaSpit extends AbstractProjectile implements LlamaSpit { @Override public net.minecraft.world.entity.projectile.LlamaSpit getHandle() { - return (net.minecraft.world.entity.projectile.LlamaSpit) super.getHandle(); - } - - @Override - public String toString() { - return "CraftLlamaSpit"; + return (net.minecraft.world.entity.projectile.LlamaSpit) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java index 58b638ffd..8720425ea 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java @@ -13,9 +13,4 @@ public class CraftMagmaCube extends CraftSlime implements MagmaCube { public net.minecraft.world.entity.monster.MagmaCube getHandle() { return (net.minecraft.world.entity.monster.MagmaCube) this.entity; } - - @Override - public String toString() { - return "CraftMagmaCube"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMarker.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMarker.java index e6782a48d..9a9302fe5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMarker.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMarker.java @@ -11,11 +11,6 @@ public class CraftMarker extends CraftEntity implements Marker { @Override public net.minecraft.world.entity.Marker getHandle() { - return (net.minecraft.world.entity.Marker) super.getHandle(); - } - - @Override - public String toString() { - return "CraftMarker"; + return (net.minecraft.world.entity.Marker) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java index 2828cd3f9..9c5caa4b9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java @@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.vehicle.AbstractMinecart; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Material; import org.bukkit.block.data.BlockData; @@ -16,10 +15,16 @@ import org.bukkit.util.Vector; import java.util.Optional; public abstract class CraftMinecart extends CraftVehicle implements Minecart { + public CraftMinecart(CraftServer server, AbstractMinecart entity) { super(server, entity); } + @Override + public AbstractMinecart getHandle() { + return (AbstractMinecart) this.entity; + } + @Override public void setDamage(double damage) { this.getHandle().setDamage((float) damage); @@ -79,11 +84,6 @@ public abstract class CraftMinecart extends CraftVehicle implements Minecart { } // Paper end - @Override - public AbstractMinecart getHandle() { - return (AbstractMinecart) this.entity; - } - @Override public void setDisplayBlock(MaterialData material) { this.getHandle().setCustomDisplayBlockState(Optional.ofNullable(material).map(CraftMagicNumbers::getBlock)); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java index 10cb6046d..0a3581cdc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java @@ -7,6 +7,7 @@ import org.bukkit.entity.minecart.StorageMinecart; import org.bukkit.inventory.Inventory; public class CraftMinecartChest extends CraftMinecartContainer implements StorageMinecart, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper + private final CraftInventory inventory; public CraftMinecartChest(CraftServer server, MinecartChest entity) { @@ -18,9 +19,4 @@ public class CraftMinecartChest extends CraftMinecartContainer implements Storag public Inventory getInventory() { return this.inventory; } - - @Override - public String toString() { - return "CraftMinecartChest{" + "inventory=" + this.inventory + '}'; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java index 663c1909e..4279824f8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java @@ -14,6 +14,7 @@ import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart, io.papermc.paper.commands.PaperCommandBlockHolder { + private final PermissibleBase perm = new PermissibleBase(this); public CraftMinecartCommand(CraftServer server, MinecartCommandBlock entity) { @@ -41,11 +42,6 @@ public class CraftMinecartCommand extends CraftMinecart implements CommandMineca this.getHandle().getCommandBlock().setCustomName(CraftChatMessage.fromStringOrNull(name)); } - @Override - public String toString() { - return "CraftMinecartCommand"; - } - @Override public void sendMessage(String message) { } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java index 561b27472..65d808c2b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java @@ -6,6 +6,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.minecart.PoweredMinecart; public class CraftMinecartFurnace extends CraftMinecart implements PoweredMinecart { + public CraftMinecartFurnace(CraftServer server, MinecartFurnace entity) { super(server, entity); } @@ -47,9 +48,4 @@ public class CraftMinecartFurnace extends CraftMinecart implements PoweredMineca final net.minecraft.world.phys.Vec3 push = this.getHandle().push; this.getHandle().push = new net.minecraft.world.phys.Vec3(push.x, push.y, zPush); } - - @Override - public String toString() { - return "CraftMinecartFurnace"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java index 700624a12..7933ee5f7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java @@ -6,7 +6,8 @@ import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.entity.minecart.HopperMinecart; import org.bukkit.inventory.Inventory; -public final class CraftMinecartHopper extends CraftMinecartContainer implements HopperMinecart, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper +public class CraftMinecartHopper extends CraftMinecartContainer implements HopperMinecart, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper + private final CraftInventory inventory; public CraftMinecartHopper(CraftServer server, MinecartHopper entity) { @@ -15,8 +16,8 @@ public final class CraftMinecartHopper extends CraftMinecartContainer implements } @Override - public String toString() { - return "CraftMinecartHopper{" + "inventory=" + this.inventory + '}'; + public net.minecraft.world.entity.vehicle.MinecartHopper getHandle() { + return (net.minecraft.world.entity.vehicle.MinecartHopper) this.entity; } @Override @@ -34,11 +35,6 @@ public final class CraftMinecartHopper extends CraftMinecartContainer implements this.getHandle().setEnabled(enabled); } - @Override - public net.minecraft.world.entity.vehicle.MinecartHopper getHandle() { - return (net.minecraft.world.entity.vehicle.MinecartHopper) super.getHandle(); - } - @Override public int getPickupCooldown() { throw new UnsupportedOperationException("Hopper minecarts don't have cooldowns"); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java index 40b62dd46..704635f20 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java @@ -16,11 +16,17 @@ import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntityType; import org.bukkit.entity.minecart.SpawnerMinecart; -final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMinecart, org.bukkit.craftbukkit.spawner.PaperSharedSpawnerLogic { // Paper - more spawner API - CraftMinecartMobSpawner(CraftServer server, MinecartSpawner entity) { +public class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMinecart, org.bukkit.craftbukkit.spawner.PaperSharedSpawnerLogic { // Paper - more spawner API + + public CraftMinecartMobSpawner(CraftServer server, MinecartSpawner entity) { super(server, entity); } + @Override + public MinecartSpawner getHandle() { + return (MinecartSpawner) this.entity; + } + @Override public EntityType getSpawnedType() { SpawnData spawnData = this.getHandle().getSpawner().nextSpawnData; @@ -162,16 +168,6 @@ final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMine this.getHandle().getSpawner().spawnRange = spawnRange; } - @Override - public MinecartSpawner getHandle() { - return (MinecartSpawner) this.entity; - } - - @Override - public String toString() { - return "CraftMinecartMobSpawner"; - } - @Override public net.minecraft.world.level.BaseSpawner getSpawner() { return this.getHandle().getSpawner(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java index 2f8c3f907..a043737f0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java @@ -1,16 +1,12 @@ package org.bukkit.craftbukkit.entity; -import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.entity.vehicle.Minecart; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.minecart.RideableMinecart; public class CraftMinecartRideable extends CraftMinecart implements RideableMinecart { - public CraftMinecartRideable(CraftServer server, AbstractMinecart entity) { + + public CraftMinecartRideable(CraftServer server, Minecart entity) { super(server, entity); } - - @Override - public String toString() { - return "CraftMinecartRideable"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java index 1fdf9e9be..bbe67e82a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java @@ -6,11 +6,17 @@ import net.minecraft.world.entity.vehicle.MinecartTNT; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.minecart.ExplosiveMinecart; -public final class CraftMinecartTNT extends CraftMinecart implements ExplosiveMinecart { - CraftMinecartTNT(CraftServer server, MinecartTNT entity) { +public class CraftMinecartTNT extends CraftMinecart implements ExplosiveMinecart { + + public CraftMinecartTNT(CraftServer server, MinecartTNT entity) { super(server, entity); } + @Override + public MinecartTNT getHandle() { + return (MinecartTNT) this.entity; + } + @Override public float getYield() { return this.getHandle().explosionPowerBase; @@ -72,14 +78,4 @@ public final class CraftMinecartTNT extends CraftMinecart implements ExplosiveMi this.getHandle().explode(power); } - - @Override - public MinecartTNT getHandle() { - return (MinecartTNT) super.getHandle(); - } - - @Override - public String toString() { - return "CraftMinecartTNT"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java index 2c8ec3a30..e2e7743bd 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java @@ -12,13 +12,30 @@ import org.bukkit.entity.Mob; import org.bukkit.loot.LootTable; public abstract class CraftMob extends CraftLivingEntity implements Mob, io.papermc.paper.entity.PaperLeashable { // Paper - Leashable API - public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) { - super(server, entity); - paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper - Mob Pathfinding API - } private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper - Mob Pathfinding API - @Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper - Mob Pathfinding API + + public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) { + super(server, entity); + this.paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper - Mob Pathfinding API + } + + @Override + public net.minecraft.world.entity.Mob getHandle() { + return (net.minecraft.world.entity.Mob) this.entity; + } + + @Override + public void setHandle(net.minecraft.world.entity.Entity entity) { + super.setHandle(entity); + this.paperPathfinder.setHandle(getHandle()); + } + + @Override + public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { + return this.paperPathfinder; + } + @Override public void setTarget(LivingEntity target) { Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation"); @@ -54,24 +71,6 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob, io.pape return (sound != null) ? CraftSound.minecraftToBukkit(sound) : null; } - @Override - public net.minecraft.world.entity.Mob getHandle() { - return (net.minecraft.world.entity.Mob) this.entity; - } - - // Paper start - Mob Pathfinding API - @Override - public void setHandle(net.minecraft.world.entity.Entity entity) { - super.setHandle(entity); - paperPathfinder.setHandle(getHandle()); - } - // Paper end - Mob Pathfinding API - - @Override - public String toString() { - return "CraftMob"; - } - @Override public void setLootTable(LootTable table) { this.getHandle().lootTable = Optional.ofNullable(CraftLootTable.bukkitToMinecraft(table)); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java index 706c74c83..52c165714 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java @@ -13,9 +13,4 @@ public class CraftMonster extends CraftCreature implements Monster, CraftEnemy { public net.minecraft.world.entity.monster.Monster getHandle() { return (net.minecraft.world.entity.monster.Monster) this.entity; } - - @Override - public String toString() { - return "CraftMonster"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMule.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMule.java index 97820a5da..075bf368f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMule.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMule.java @@ -10,11 +10,6 @@ public class CraftMule extends CraftChestedHorse implements Mule { super(server, entity); } - @Override - public String toString() { - return "CraftMule"; - } - @Override public Variant getVariant() { return Variant.MULE; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java index 1ac8b1a1b..fb25c0f55 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java @@ -5,7 +5,6 @@ import com.google.common.collect.ImmutableList; import java.util.List; import net.minecraft.core.Holder; import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.item.component.SuspiciousStewEffects; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.potion.CraftPotionEffectType; @@ -15,10 +14,16 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; public class CraftMushroomCow extends CraftAbstractCow implements MushroomCow, io.papermc.paper.entity.PaperShearable { // Paper + public CraftMushroomCow(CraftServer server, net.minecraft.world.entity.animal.MushroomCow entity) { super(server, entity); } + @Override + public net.minecraft.world.entity.animal.MushroomCow getHandle() { + return (net.minecraft.world.entity.animal.MushroomCow) this.entity; + } + @Override public boolean hasEffectsForNextStew() { SuspiciousStewEffects stewEffects = this.getHandle().stewEffects; @@ -92,11 +97,6 @@ public class CraftMushroomCow extends CraftAbstractCow implements MushroomCow, i this.getHandle().stewEffects = null; } - @Override - public net.minecraft.world.entity.animal.MushroomCow getHandle() { - return (net.minecraft.world.entity.animal.MushroomCow) this.entity; - } - @Override public Variant getVariant() { return Variant.values()[this.getHandle().getVariant().ordinal()]; @@ -145,9 +145,4 @@ public class CraftMushroomCow extends CraftAbstractCow implements MushroomCow, i this.getHandle().stewEffects = new SuspiciousStewEffects(nmsPairs); } // Paper end - - @Override - public String toString() { - return "CraftMushroomCow"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java index 2953a311e..b4685c977 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java @@ -4,6 +4,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Ocelot; public class CraftOcelot extends CraftAnimals implements Ocelot { + public CraftOcelot(CraftServer server, net.minecraft.world.entity.animal.Ocelot ocelot) { super(server, ocelot); } @@ -32,9 +33,4 @@ public class CraftOcelot extends CraftAnimals implements Ocelot { public void setCatType(Type type) { throw new UnsupportedOperationException("Cats are now a different entity!"); } - - @Override - public String toString() { - return "CraftOcelot"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOminousItemSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOminousItemSpawner.java index ecdac2cf7..c8cc8a695 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOminousItemSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftOminousItemSpawner.java @@ -16,11 +16,6 @@ public class CraftOminousItemSpawner extends CraftEntity implements OminousItemS return (net.minecraft.world.entity.OminousItemSpawner) this.entity; } - @Override - public String toString() { - return "CraftOminousItemSpawner"; - } - @Override public ItemStack getItem() { return CraftItemStack.asBukkitCopy(this.getHandle().getItem()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java index bcac1359c..614a17330 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java @@ -14,6 +14,11 @@ public class CraftPainting extends CraftHanging implements Painting { super(server, entity); } + @Override + public net.minecraft.world.entity.decoration.Painting getHandle() { + return (net.minecraft.world.entity.decoration.Painting) this.entity; + } + @Override public Art getArt() { return CraftArt.minecraftHolderToBukkit(this.getHandle().getVariant()); @@ -49,14 +54,4 @@ public class CraftPainting extends CraftHanging implements Painting { return false; } - - @Override - public net.minecraft.world.entity.decoration.Painting getHandle() { - return (net.minecraft.world.entity.decoration.Painting) this.entity; - } - - @Override - public String toString() { - return "CraftPainting{art=" + this.getArt() + "}"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java index 3e073a268..df2877d05 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java @@ -12,12 +12,7 @@ public class CraftPanda extends CraftAnimals implements Panda { @Override public net.minecraft.world.entity.animal.Panda getHandle() { - return (net.minecraft.world.entity.animal.Panda) super.getHandle(); - } - - @Override - public String toString() { - return "CraftPanda"; + return (net.minecraft.world.entity.animal.Panda) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftParrot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftParrot.java index 0c6cd6bfe..60e1da70c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftParrot.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftParrot.java @@ -3,7 +3,6 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Parrot; -import org.bukkit.entity.Parrot.Variant; public class CraftParrot extends CraftTameableAnimal implements Parrot { @@ -28,11 +27,6 @@ public class CraftParrot extends CraftTameableAnimal implements Parrot { this.getHandle().setVariant(net.minecraft.world.entity.animal.Parrot.Variant.byId(variant.ordinal())); } - @Override - public String toString() { - return "CraftParrot"; - } - @Override public boolean isDancing() { return this.getHandle().isPartyParrot(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java index 37d15a0b1..ffeb5adc0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java @@ -15,7 +15,7 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy { @Override public net.minecraft.world.entity.monster.Phantom getHandle() { - return (net.minecraft.world.entity.monster.Phantom) super.getHandle(); + return (net.minecraft.world.entity.monster.Phantom) this.entity; } @Override @@ -28,11 +28,6 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy { this.getHandle().setPhantomSize(size); } - @Override - public String toString() { - return "CraftPhantom"; - } - @Override public UUID getSpawningEntity() { return this.getHandle().spawningEntity; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java index be50162e5..91f1e61e3 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java @@ -9,10 +9,8 @@ import net.minecraft.world.entity.animal.PigVariant; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import org.bukkit.Material; -import org.bukkit.NamespacedKey; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.entity.Pig; import org.jspecify.annotations.NullMarked; @@ -23,6 +21,11 @@ public class CraftPig extends CraftAnimals implements Pig { super(server, entity); } + @Override + public net.minecraft.world.entity.animal.Pig getHandle() { + return (net.minecraft.world.entity.animal.Pig) this.entity; + } + @Override public boolean hasSaddle() { return this.getHandle().isSaddled(); @@ -101,14 +104,4 @@ public class CraftPig extends CraftAnimals implements Pig { super(holder); } } - - @Override - public net.minecraft.world.entity.animal.Pig getHandle() { - return (net.minecraft.world.entity.animal.Pig) this.entity; - } - - @Override - public String toString() { - return "CraftPig"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java index 49beb836d..fa9d7a532 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java @@ -10,6 +10,11 @@ public class CraftPigZombie extends CraftZombie implements PigZombie { super(server, entity); } + @Override + public ZombifiedPiglin getHandle() { + return (ZombifiedPiglin) this.entity; + } + @Override public int getAnger() { return this.getHandle().getRemainingPersistentAngerTime(); @@ -30,16 +35,6 @@ public class CraftPigZombie extends CraftZombie implements PigZombie { return this.getAnger() > 0; } - @Override - public ZombifiedPiglin getHandle() { - return (ZombifiedPiglin) this.entity; - } - - @Override - public String toString() { - return "CraftPigZombie"; - } - @Override public boolean isConverting() { return false; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java index e12ad80bc..849873a9f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java @@ -18,6 +18,11 @@ public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.dest super(server, entity); } + @Override + public net.minecraft.world.entity.monster.piglin.Piglin getHandle() { + return (net.minecraft.world.entity.monster.piglin.Piglin) this.entity; + } + @Override public boolean isAbleToHunt() { return this.getHandle().cannotHunt; @@ -75,16 +80,6 @@ public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.dest return new CraftInventory(this.getHandle().inventory); } - @Override - public net.minecraft.world.entity.monster.piglin.Piglin getHandle() { - return (net.minecraft.world.entity.monster.piglin.Piglin) super.getHandle(); - } - - @Override - public String toString() { - return "CraftPiglin"; - } - @Override public void setChargingCrossbow(boolean chargingCrossbow) { this.getHandle().setChargingCrossbow(chargingCrossbow); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinAbstract.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinAbstract.java index e7957d605..a30bbedaf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinAbstract.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinAbstract.java @@ -11,6 +11,11 @@ public class CraftPiglinAbstract extends CraftMonster implements PiglinAbstract super(server, entity); } + @Override + public AbstractPiglin getHandle() { + return (AbstractPiglin) this.entity; + } + @Override public boolean isImmuneToZombification() { return this.getHandle().isImmuneToZombification(); @@ -94,9 +99,4 @@ public class CraftPiglinAbstract extends CraftMonster implements PiglinAbstract @Override public void setBreed(boolean b) { } - - @Override - public AbstractPiglin getHandle() { - return (AbstractPiglin) super.getHandle(); - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinBrute.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinBrute.java index be874dc97..2fa281466 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinBrute.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglinBrute.java @@ -11,11 +11,6 @@ public class CraftPiglinBrute extends CraftPiglinAbstract implements PiglinBrute @Override public net.minecraft.world.entity.monster.piglin.PiglinBrute getHandle() { - return (net.minecraft.world.entity.monster.piglin.PiglinBrute) super.getHandle(); - } - - @Override - public String toString() { - return "CraftPiglinBrute"; + return (net.minecraft.world.entity.monster.piglin.PiglinBrute) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java index 2638c341b..d927938df 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java @@ -13,12 +13,7 @@ public class CraftPillager extends CraftIllager implements Pillager, com.destroy @Override public net.minecraft.world.entity.monster.Pillager getHandle() { - return (net.minecraft.world.entity.monster.Pillager) super.getHandle(); - } - - @Override - public String toString() { - return "CraftPillager"; + return (net.minecraft.world.entity.monster.Pillager) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index df6612a86..1db6276ae 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -12,6 +12,8 @@ import io.papermc.paper.configuration.GlobalConfiguration; import io.papermc.paper.entity.LookAnchor; import io.papermc.paper.entity.PaperPlayerGiveResult; import io.papermc.paper.entity.PlayerGiveResult; +import io.papermc.paper.math.Position; +import io.papermc.paper.util.MCUtil; import it.unimi.dsi.fastutil.shorts.ShortArraySet; import it.unimi.dsi.fastutil.shorts.ShortSet; import java.io.ByteArrayOutputStream; @@ -42,7 +44,8 @@ import java.util.concurrent.CompletableFuture; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.annotation.Nullable; +import net.kyori.adventure.util.TriState; +import net.md_5.bungee.api.chat.BaseComponent; import net.minecraft.advancements.AdvancementProgress; import net.minecraft.commands.Commands; import net.minecraft.core.BlockPos; @@ -72,6 +75,7 @@ import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; import net.minecraft.network.protocol.game.ClientboundLevelEventPacket; import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket; import net.minecraft.network.protocol.game.ClientboundMapItemDataPacket; +import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket; @@ -201,12 +205,12 @@ import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scoreboard.Scoreboard; -import org.jetbrains.annotations.NotNull; - -import net.md_5.bungee.api.chat.BaseComponent; // Spigot +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; @DelegateDeserialization(CraftOfflinePlayer.class) public class CraftPlayer extends CraftHumanEntity implements Player { + private long firstPlayed = 0; private long lastPlayed = 0; private boolean hasPlayedBefore = false; @@ -223,7 +227,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener(); public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit - private boolean simplifyContainerDesyncCheck = GlobalConfiguration.get().unsupportedSettings.simplifyRemoteItemMatching; private long lastSaveTime; // Paper - getLastPlayed replacement API public CraftPlayer(CraftServer server, ServerPlayer entity) { @@ -232,6 +235,27 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.firstPlayed = System.currentTimeMillis(); } + @Override + public ServerPlayer getHandle() { + return (ServerPlayer) this.entity; + } + + @Override + public boolean equals(Object obj) { + // Long-term, this should just use the super equals... for now, check the UUID + if (obj == this) return true; + if (!(obj instanceof OfflinePlayer other)) return false; + return this.getUniqueId().equals(other.getUniqueId()); + } + + @Override + public int hashCode() { + if (this.hash == 0 || this.hash == 485) { + this.hash = 97 * 5 + this.getUniqueId().hashCode(); + } + return this.hash; + } + public GameProfile getProfile() { return this.getHandle().getGameProfile(); } @@ -308,7 +332,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { void kickPlayer(Component reason, org.bukkit.event.player.PlayerKickEvent.Cause cause); // Paper - kick event causes } - public record CookieFuture(ResourceLocation key, CompletableFuture future) { + public record CookieFuture(ResourceLocation key, CompletableFuture future) { } private final Queue requestedCookies = new LinkedList<>(); @@ -337,10 +361,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public CompletableFuture retrieveCookie(NamespacedKey key) { + public CompletableFuture retrieveCookie(final NamespacedKey key) { Preconditions.checkArgument(key != null, "Cookie key cannot be null"); - CompletableFuture future = new CompletableFuture<>(); + CompletableFuture future = new CompletableFuture<>(); ResourceLocation nms = CraftNamespacedKey.toMinecraft(key); this.requestedCookies.add(new CookieFuture(nms, future)); @@ -438,7 +462,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override @Deprecated public void sendActionBar(BaseComponent[] message) { - if (getHandle().connection == null) return; + if (getHandle().connection == null || message == null) return; net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket packet = new net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket(org.bukkit.craftbukkit.util.CraftChatMessage.bungeeToVanilla(message)); getHandle().connection.send(packet); } @@ -458,7 +482,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) { + public void setPlayerListHeaderFooter(BaseComponent @Nullable [] header, BaseComponent @Nullable [] footer) { if (header != null) { String headerJson = CraftChatMessage.bungeeToJson(header); playerListHeader = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().deserialize(headerJson); @@ -477,12 +501,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void setPlayerListHeaderFooter(BaseComponent header, BaseComponent footer) { + public void setPlayerListHeaderFooter(@Nullable BaseComponent header, @Nullable BaseComponent footer) { this.setPlayerListHeaderFooter(header == null ? null : new BaseComponent[]{header}, footer == null ? null : new BaseComponent[]{footer}); } - @Override public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks) { getHandle().connection.send(new ClientboundSetTitlesAnimationPacket(fadeInTicks, stayTicks, fadeOutTicks)); @@ -662,14 +685,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } - @Override - public boolean equals(Object obj) { - // Long-term, this should just use the super equals... for now, check the UUID - if (obj == this) return true; - if (!(obj instanceof OfflinePlayer other)) return false; - return this.getUniqueId().equals(other.getUniqueId()); - } - @Override public void kickPlayer(String message) { org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot @@ -724,7 +739,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void addAdditionalChatCompletions(@NotNull Collection completions) { + public void addAdditionalChatCompletions(@NonNull Collection completions) { this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket( net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket.Action.ADD, new ArrayList<>(completions) @@ -732,7 +747,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void removeAdditionalChatCompletions(@NotNull Collection completions) { + public void removeAdditionalChatCompletions(@NonNull Collection completions) { this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket( net.minecraft.network.protocol.game.ClientboundCustomChatCompletionsPacket.Action.REMOVE, new ArrayList<>(completions) @@ -1089,17 +1104,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end @Override - public void sendSignChange(Location loc, String[] lines) { + public void sendSignChange(Location loc, @Nullable String @Nullable [] lines) { this.sendSignChange(loc, lines, DyeColor.BLACK); } @Override - public void sendSignChange(Location loc, String[] lines, DyeColor dyeColor) { + public void sendSignChange(Location loc, @Nullable String @Nullable [] lines, DyeColor dyeColor) { this.sendSignChange(loc, lines, dyeColor, false); } @Override - public void sendSignChange(Location loc, String[] lines, DyeColor dyeColor, boolean hasGlowingText) { + public void sendSignChange(Location loc, @Nullable String @Nullable [] lines, DyeColor dyeColor, boolean hasGlowingText) { Preconditions.checkArgument(loc != null, "Location cannot be null"); Preconditions.checkArgument(dyeColor != null, "DyeColor cannot be null"); @@ -1130,7 +1145,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void sendBlockUpdate(@NotNull Location location, @NotNull TileState tileState) throws IllegalArgumentException { + public void sendBlockUpdate(@NonNull Location location, @NonNull TileState tileState) throws IllegalArgumentException { Preconditions.checkArgument(location != null, "Location can not be null"); Preconditions.checkArgument(tileState != null, "TileState can not be null"); @@ -1141,12 +1156,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, ItemStack item) { - this.sendEquipmentChange(entity, java.util.Collections.singletonMap(slot, item)); // Paper - replace Map.of to allow null values + public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, @Nullable ItemStack item) { + this.sendEquipmentChange(entity, java.util.Collections.singletonMap(slot, item)); } @Override - public void sendEquipmentChange(LivingEntity entity, Map items) { + public void sendEquipmentChange(LivingEntity entity, Map items) { Preconditions.checkArgument(entity != null, "Entity cannot be null"); Preconditions.checkArgument(items != null, "items cannot be null"); Preconditions.checkArgument(!items.isEmpty(), "items cannot be empty"); @@ -1368,7 +1383,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull LookAnchor playerAnchor, @NotNull LookAnchor entityAnchor) { + public void lookAt(org.bukkit.entity.@NonNull Entity entity, @NonNull LookAnchor playerAnchor, @NonNull LookAnchor entityAnchor) { this.getHandle().lookAt(toNmsAnchor(playerAnchor), ((CraftEntity) entity).getHandle(), toNmsAnchor(entityAnchor)); } @@ -1541,19 +1556,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public Location getRespawnLocation() { + public Location getRespawnLocation(final boolean loadLocationAndValidate) { final ServerPlayer.RespawnConfig respawnConfig = this.getHandle().getRespawnConfig(); if (respawnConfig == null) return null; - ServerLevel world = this.getHandle().server.getLevel(respawnConfig.dimension()); - if (world != null) { - Optional spawnLoc = ServerPlayer.findRespawnAndUseSpawnBlock(world, respawnConfig, true); - if (spawnLoc.isPresent()) { - ServerPlayer.RespawnPosAngle vec = spawnLoc.get(); - return CraftLocation.toBukkit(vec.position(), world.getWorld(), vec.yaw(), 0); - } + final ServerLevel world = this.getHandle().server.getLevel(respawnConfig.dimension()); + if (world == null) return null; + + if (!loadLocationAndValidate) { + return CraftLocation.toBukkit(respawnConfig.pos(), world.getWorld(), respawnConfig.angle(), 0); } - return null; + + return ServerPlayer.findRespawnAndUseSpawnBlock(world, respawnConfig, false) + .map(pos -> CraftLocation.toBukkit(pos.position(), world.getWorld(), pos.yaw(), 0)) + .orElse(null); } @Override @@ -1993,8 +2009,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(packet); } - @Nullable - private static WeakReference getPluginWeakReference(@Nullable Plugin plugin) { + private static @Nullable WeakReference getPluginWeakReference(@Nullable Plugin plugin) { return (plugin == null) ? null : CraftPlayer.pluginWeakReferences.computeIfAbsent(plugin, WeakReference::new); } @@ -2263,7 +2278,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public boolean unlistPlayer(@NotNull Player other) { + public boolean unlistPlayer(@NonNull Player other) { Preconditions.checkNotNull(other, "hidden entity cannot be null"); if (this.getHandle().connection == null) return false; if (!this.canSee(other)) return false; @@ -2277,7 +2292,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public boolean listPlayer(@NotNull Player other) { + public boolean listPlayer(@NonNull Player other) { Preconditions.checkNotNull(other, "hidden entity cannot be null"); if (this.getHandle().connection == null) return false; if (!this.canSee(other)) throw new IllegalStateException("Player cannot see other player"); @@ -2305,28 +2320,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return this; } - @Override - public ServerPlayer getHandle() { - return (ServerPlayer) this.entity; - } - - public void setHandle(final ServerPlayer entity) { - super.setHandle(entity); - } - - @Override - public String toString() { - return "CraftPlayer{" + "name=" + this.getName() + '}'; - } - - @Override - public int hashCode() { - if (this.hash == 0 || this.hash == 485) { - this.hash = 97 * 5 + this.getUniqueId().hashCode(); - } - return this.hash; - } - @Override public long getFirstPlayed() { return this.firstPlayed; @@ -2454,29 +2447,29 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void setResourcePack(String url, byte[] hash) { + public void setResourcePack(String url, byte @Nullable [] hash) { this.setResourcePack(url, hash, false); } @Override - public void setResourcePack(String url, byte[] hash, String prompt) { + public void setResourcePack(String url, byte @Nullable [] hash, String prompt) { this.setResourcePack(url, hash, prompt, false); } @Override - public void setResourcePack(String url, byte[] hash, boolean force) { + public void setResourcePack(String url, byte @Nullable [] hash, boolean force) { this.setResourcePack(url, hash, (String) null, force); } @Override - public void setResourcePack(String url, byte[] hash, String prompt, boolean force) { + public void setResourcePack(String url, byte @Nullable [] hash, String prompt, boolean force) { Preconditions.checkArgument(url != null, "Resource pack URL cannot be null"); this.setResourcePack(UUID.nameUUIDFromBytes(url.getBytes(StandardCharsets.UTF_8)), url, hash, prompt, force); } @Override - public void setResourcePack(UUID id, String url, byte[] hash, String prompt, boolean force) { + public void setResourcePack(UUID id, String url, byte @Nullable [] hash, String prompt, boolean force) { Preconditions.checkArgument(id != null, "Resource pack ID cannot be null"); Preconditions.checkArgument(url != null, "Resource pack URL cannot be null"); @@ -2490,7 +2483,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void addResourcePack(UUID id, String url, byte[] hash, String prompt, boolean force) { + public void addResourcePack(UUID id, String url, byte @Nullable [] hash, String prompt, boolean force) { Preconditions.checkArgument(url != null, "Resource pack URL cannot be null"); String hashStr = ""; @@ -2504,7 +2497,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - adventure @Override - public void setResourcePack(final UUID uuid, final String url, final byte[] hashBytes, final net.kyori.adventure.text.Component prompt, final boolean force) { + public void setResourcePack(final UUID uuid, final String url, final byte @Nullable [] hashBytes, final net.kyori.adventure.text.Component prompt, final boolean force) { Preconditions.checkArgument(uuid != null, "Resource pack UUID cannot be null"); Preconditions.checkArgument(url != null, "Resource pack URL cannot be null"); final String hash; @@ -2543,7 +2536,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void removeResourcePacks(final UUID id, final UUID ... others) { + public void removeResourcePacks(final UUID id, final UUID... others) { if (this.getHandle().connection == null) return; this.sendBundle(net.kyori.adventure.util.MonkeyBars.nonEmptyArrayToList(pack -> new ClientboundResourcePackPopPacket(Optional.of(pack)), id, others)); } @@ -2692,13 +2685,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - flying fall damage @Override - public void setFlyingFallDamage(@NotNull net.kyori.adventure.util.TriState flyingFallDamage) { + public void setFlyingFallDamage(@NonNull TriState flyingFallDamage) { getHandle().flyingFallDamage = flyingFallDamage; } - @NotNull @Override - public net.kyori.adventure.util.TriState hasFlyingFallDamage() { + public @NonNull TriState hasFlyingFallDamage() { return getHandle().flyingFallDamage; } // Paper end - flying fall damage @@ -3044,10 +3036,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } @Override - public void openSign(@NotNull Sign sign, @NotNull Side side) { + public void openSign(@NonNull Sign sign, @NonNull Side side) { CraftSign.openSign(sign, this, side); } + @Override + public void openVirtualSign(Position block, Side side) { + if (this.getHandle().connection == null) return; + + this.getHandle().connection.send(new ClientboundOpenSignEditorPacket(MCUtil.toBlockPos(block), side == Side.FRONT)); + } + @Override public void showDemoScreen() { if (this.getHandle().connection == null) return; @@ -3214,7 +3213,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { private @Nullable Set activeBossBars; @Override - public @NotNull Iterable activeBossBars() { + public @NonNull Iterable activeBossBars() { if (this.activeBossBars != null) { return java.util.Collections.unmodifiableSet(this.activeBossBars); } @@ -3522,7 +3521,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper end - entity effect API @Override - public @NotNull PlayerGiveResult give(@NotNull final Collection<@NotNull ItemStack> items, final boolean dropIfFull) { + public @NonNull PlayerGiveResult give(final @NonNull Collection<@NonNull ItemStack> items, final boolean dropIfFull) { Preconditions.checkArgument(items != null, "items cannot be null"); if (items.isEmpty()) return PaperPlayerGiveResult.EMPTY; // Early opt out for empty input. @@ -3577,20 +3576,4 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void setDeathScreenScore(final int score) { getHandle().setScore(score); } - - /** - * Returns whether container desync checks should skip the full item comparison of remote carried and changed slots - * and should instead only check their type and amount. - *

- * This is useful if the client is not able to produce the same item stack (or as of 1.21.5, its data hashes) as the server. - * - * @return whether to simplify container desync checks - */ - public boolean simplifyContainerDesyncCheck() { - return simplifyContainerDesyncCheck; - } - - public void setSimplifyContainerDesyncCheck(final boolean simplifyContainerDesyncCheck) { - this.simplifyContainerDesyncCheck = simplifyContainerDesyncCheck; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPolarBear.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPolarBear.java index 3d1d5d4ea..1e3b8eb59 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPolarBear.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPolarBear.java @@ -8,16 +8,12 @@ public class CraftPolarBear extends CraftAnimals implements PolarBear { public CraftPolarBear(CraftServer server, net.minecraft.world.entity.animal.PolarBear entity) { super(server, entity); } + @Override public net.minecraft.world.entity.animal.PolarBear getHandle() { return (net.minecraft.world.entity.animal.PolarBear) this.entity; } - @Override - public String toString() { - return "CraftPolarBear"; - } - @Override public boolean isStanding() { return this.getHandle().isStanding(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java index a636182e2..94ae0f207 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java @@ -4,6 +4,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Projectile; public abstract class CraftProjectile extends AbstractProjectile implements Projectile { + public CraftProjectile(CraftServer server, net.minecraft.world.entity.projectile.Projectile entity) { super(server, entity); } @@ -12,9 +13,4 @@ public abstract class CraftProjectile extends AbstractProjectile implements Proj public net.minecraft.world.entity.projectile.Projectile getHandle() { return (net.minecraft.world.entity.projectile.Projectile) this.entity; } - - @Override - public String toString() { - return "CraftProjectile"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java index 35a821973..e63c3bdd1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPufferFish.java @@ -12,7 +12,7 @@ public class CraftPufferFish extends CraftFish implements PufferFish { @Override public Pufferfish getHandle() { - return (Pufferfish) super.getHandle(); + return (Pufferfish) this.entity; } @Override @@ -24,9 +24,4 @@ public class CraftPufferFish extends CraftFish implements PufferFish { public void setPuffState(int state) { this.getHandle().setPuffState(state); } - - @Override - public String toString() { - return "CraftPufferFish"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java index afa581272..994eb2d88 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java @@ -14,11 +14,6 @@ public class CraftRabbit extends CraftAnimals implements Rabbit { return (net.minecraft.world.entity.animal.Rabbit) this.entity; } - @Override - public String toString() { - return "CraftRabbit{RabbitType=" + this.getRabbitType() + "}"; - } - @Override public Type getRabbitType() { return Type.values()[this.getHandle().getVariant().ordinal()]; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java index 1988ba305..42d89992c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRaider.java @@ -18,12 +18,7 @@ public abstract class CraftRaider extends CraftMonster implements Raider { @Override public net.minecraft.world.entity.raid.Raider getHandle() { - return (net.minecraft.world.entity.raid.Raider) super.getHandle(); - } - - @Override - public String toString() { - return "CraftRaider"; + return (net.minecraft.world.entity.raid.Raider) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java index 42d9c9449..ec2b5fbec 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java @@ -11,12 +11,7 @@ public class CraftRavager extends CraftRaider implements Ravager { @Override public net.minecraft.world.entity.monster.Ravager getHandle() { - return (net.minecraft.world.entity.monster.Ravager) super.getHandle(); - } - - @Override - public String toString() { - return "CraftRavager"; + return (net.minecraft.world.entity.monster.Ravager) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java index cb044eae9..8b2c8924f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSalmon.java @@ -12,12 +12,7 @@ public class CraftSalmon extends io.papermc.paper.entity.PaperSchoolableFish imp @Override public net.minecraft.world.entity.animal.Salmon getHandle() { - return (net.minecraft.world.entity.animal.Salmon) super.getHandle(); - } - - @Override - public String toString() { - return "CraftSalmon"; + return (net.minecraft.world.entity.animal.Salmon) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java index 50757c1f4..95c1535a1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java @@ -5,10 +5,16 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Sheep; public class CraftSheep extends CraftAnimals implements Sheep, io.papermc.paper.entity.PaperShearable { // Paper + public CraftSheep(CraftServer server, net.minecraft.world.entity.animal.sheep.Sheep entity) { super(server, entity); } + @Override + public net.minecraft.world.entity.animal.sheep.Sheep getHandle() { + return (net.minecraft.world.entity.animal.sheep.Sheep) this.entity; + } + @Override public DyeColor getColor() { return DyeColor.getByWoolData((byte) this.getHandle().getColor().getId()); @@ -28,14 +34,4 @@ public class CraftSheep extends CraftAnimals implements Sheep, io.papermc.paper. public void setSheared(boolean flag) { this.getHandle().setSheared(flag); } - - @Override - public net.minecraft.world.entity.animal.sheep.Sheep getHandle() { - return (net.minecraft.world.entity.animal.sheep.Sheep) this.entity; - } - - @Override - public String toString() { - return "CraftSheep"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java index 05ec06b71..c23b88cad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulker.java @@ -13,11 +13,6 @@ public class CraftShulker extends CraftGolem implements Shulker, CraftEnemy { super(server, entity); } - @Override - public String toString() { - return "CraftShulker"; - } - @Override public net.minecraft.world.entity.monster.Shulker getHandle() { return (net.minecraft.world.entity.monster.Shulker) this.entity; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java index 52d0dbf17..9a1a581e5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java @@ -10,6 +10,11 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul super(server, entity); } + @Override + public net.minecraft.world.entity.projectile.ShulkerBullet getHandle() { + return (net.minecraft.world.entity.projectile.ShulkerBullet) this.entity; + } + @Override public org.bukkit.entity.Entity getTarget() { return this.getHandle().getTarget() != null ? this.getHandle().getTarget().getBukkitEntity() : null; @@ -59,14 +64,4 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul public void setFlightSteps(int steps) { this.getHandle().flightSteps = steps; } - - @Override - public String toString() { - return "CraftShulkerBullet"; - } - - @Override - public net.minecraft.world.entity.projectile.ShulkerBullet getHandle() { - return (net.minecraft.world.entity.projectile.ShulkerBullet) this.entity; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java index 7c75d78e5..d5acee3d7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java @@ -4,6 +4,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Silverfish; public class CraftSilverfish extends CraftMonster implements Silverfish { + public CraftSilverfish(CraftServer server, net.minecraft.world.entity.monster.Silverfish entity) { super(server, entity); } @@ -12,9 +13,4 @@ public class CraftSilverfish extends CraftMonster implements Silverfish { public net.minecraft.world.entity.monster.Silverfish getHandle() { return (net.minecraft.world.entity.monster.Silverfish) this.entity; } - - @Override - public String toString() { - return "CraftSilverfish"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSizedFireball.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSizedFireball.java index de3327812..579ec5453 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSizedFireball.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSizedFireball.java @@ -13,6 +13,11 @@ public class CraftSizedFireball extends CraftFireball implements SizedFireball { super(server, entity); } + @Override + public Fireball getHandle() { + return (Fireball) this.entity; + } + @Override public ItemStack getDisplayItem() { if (this.getHandle().getItem().isEmpty()) { @@ -26,9 +31,4 @@ public class CraftSizedFireball extends CraftFireball implements SizedFireball { public void setDisplayItem(ItemStack item) { this.getHandle().setItem(CraftItemStack.asNMSCopy(item)); } - - @Override - public Fireball getHandle() { - return (Fireball) this.entity; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java index 866929772..af73ee0ce 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java @@ -10,6 +10,11 @@ public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton { super(server, entity); } + @Override + public net.minecraft.world.entity.monster.Skeleton getHandle() { + return (net.minecraft.world.entity.monster.Skeleton) this.entity; + } + @Override public boolean isConverting() { return this.getHandle().isFreezeConverting(); @@ -31,16 +36,6 @@ public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton { } } - @Override - public net.minecraft.world.entity.monster.Skeleton getHandle() { - return (net.minecraft.world.entity.monster.Skeleton) this.entity; - } - - @Override - public String toString() { - return "CraftSkeleton"; - } - @Override public SkeletonType getSkeletonType() { return SkeletonType.NORMAL; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java index 248e4febb..f40729e9c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java @@ -11,8 +11,8 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo } @Override - public String toString() { - return "CraftSkeletonHorse"; + public net.minecraft.world.entity.animal.horse.SkeletonHorse getHandle() { + return (net.minecraft.world.entity.animal.horse.SkeletonHorse) this.entity; } @Override @@ -20,11 +20,6 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo return Variant.SKELETON_HORSE; } - @Override - public net.minecraft.world.entity.animal.horse.SkeletonHorse getHandle() { - return (net.minecraft.world.entity.animal.horse.SkeletonHorse) this.entity; - } - @Override public boolean isTrapped() { return this.getHandle().isTrap(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java index dde173d35..214e63670 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java @@ -9,6 +9,11 @@ public class CraftSlime extends CraftMob implements Slime, CraftEnemy { super(server, entity); } + @Override + public net.minecraft.world.entity.monster.Slime getHandle() { + return (net.minecraft.world.entity.monster.Slime) this.entity; + } + @Override public int getSize() { return this.getHandle().getSize(); @@ -19,16 +24,6 @@ public class CraftSlime extends CraftMob implements Slime, CraftEnemy { this.getHandle().setSize(size, /* true */ getHandle().isAlive()); // Paper - fix dead slime setSize invincibility } - @Override - public net.minecraft.world.entity.monster.Slime getHandle() { - return (net.minecraft.world.entity.monster.Slime) this.entity; - } - - @Override - public String toString() { - return "CraftSlime"; - } - @Override public boolean canWander() { return this.getHandle().canWander(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java index 072df2068..fbd3f86bf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java @@ -4,6 +4,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.SmallFireball; public class CraftSmallFireball extends CraftSizedFireball implements SmallFireball { + public CraftSmallFireball(CraftServer server, net.minecraft.world.entity.projectile.SmallFireball entity) { super(server, entity); } @@ -12,9 +13,4 @@ public class CraftSmallFireball extends CraftSizedFireball implements SmallFireb public net.minecraft.world.entity.projectile.SmallFireball getHandle() { return (net.minecraft.world.entity.projectile.SmallFireball) this.entity; } - - @Override - public String toString() { - return "CraftSmallFireball"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java index 7a9abd3af..808b037b6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSniffer.java @@ -18,12 +18,7 @@ public class CraftSniffer extends CraftAnimals implements Sniffer { @Override public net.minecraft.world.entity.animal.sniffer.Sniffer getHandle() { - return (net.minecraft.world.entity.animal.sniffer.Sniffer) super.getHandle(); - } - - @Override - public String toString() { - return "CraftSniffer"; + return (net.minecraft.world.entity.animal.sniffer.Sniffer) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java index d959825fd..b31f2a939 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java @@ -4,6 +4,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Snowball; public class CraftSnowball extends CraftThrowableProjectile implements Snowball { + public CraftSnowball(CraftServer server, net.minecraft.world.entity.projectile.Snowball entity) { super(server, entity); } @@ -12,9 +13,4 @@ public class CraftSnowball extends CraftThrowableProjectile implements Snowball public net.minecraft.world.entity.projectile.Snowball getHandle() { return (net.minecraft.world.entity.projectile.Snowball) this.entity; } - - @Override - public String toString() { - return "CraftSnowball"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java index 4ce2373ff..f03f9f94c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java @@ -5,10 +5,16 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Snowman; public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity, io.papermc.paper.entity.PaperShearable { // Paper + public CraftSnowman(CraftServer server, SnowGolem entity) { super(server, entity); } + @Override + public SnowGolem getHandle() { + return (SnowGolem) this.entity; + } + @Override public boolean isDerp() { return !this.getHandle().hasPumpkin(); @@ -18,14 +24,4 @@ public class CraftSnowman extends CraftGolem implements Snowman, com.destroystok public void setDerp(boolean derpMode) { this.getHandle().setPumpkin(!derpMode); } - - @Override - public SnowGolem getHandle() { - return (SnowGolem) this.entity; - } - - @Override - public String toString() { - return "CraftSnowman"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpectralArrow.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpectralArrow.java index 70f1f8740..4afd6e013 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpectralArrow.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpectralArrow.java @@ -14,11 +14,6 @@ public class CraftSpectralArrow extends CraftAbstractArrow implements SpectralAr return (net.minecraft.world.entity.projectile.SpectralArrow) this.entity; } - @Override - public String toString() { - return "CraftSpectralArrow"; - } - @Override public int getGlowingTicks() { return this.getHandle().duration; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpellcaster.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpellcaster.java index 525827f17..b28ef9d00 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpellcaster.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpellcaster.java @@ -4,7 +4,6 @@ import com.google.common.base.Preconditions; import net.minecraft.world.entity.monster.SpellcasterIllager; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Spellcaster; -import org.bukkit.entity.Spellcaster.Spell; public class CraftSpellcaster extends CraftIllager implements Spellcaster { @@ -14,12 +13,7 @@ public class CraftSpellcaster extends CraftIllager implements Spellcaster { @Override public SpellcasterIllager getHandle() { - return (SpellcasterIllager) super.getHandle(); - } - - @Override - public String toString() { - return "CraftSpellcaster"; + return (SpellcasterIllager) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java index b4afc37c2..90be754d6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java @@ -13,9 +13,4 @@ public class CraftSpider extends CraftMonster implements Spider { public net.minecraft.world.entity.monster.Spider getHandle() { return (net.minecraft.world.entity.monster.Spider) this.entity; } - - @Override - public String toString() { - return "CraftSpider"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java index 067a95ea5..d1a49aaa2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java @@ -13,9 +13,4 @@ public class CraftSquid extends CraftAgeable implements Squid { public net.minecraft.world.entity.animal.Squid getHandle() { return (net.minecraft.world.entity.animal.Squid) this.entity; } - - @Override - public String toString() { - return "CraftSquid"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStray.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStray.java index 833290525..397ca2e09 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStray.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStray.java @@ -10,11 +10,6 @@ public class CraftStray extends CraftAbstractSkeleton implements Stray { super(server, entity); } - @Override - public String toString() { - return "CraftStray"; - } - @Override public SkeletonType getSkeletonType() { return SkeletonType.STRAY; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java index 53f067346..6c03adc7b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftStrider.java @@ -14,6 +14,11 @@ public class CraftStrider extends CraftAnimals implements Strider { super(server, entity); } + @Override + public net.minecraft.world.entity.monster.Strider getHandle() { + return (net.minecraft.world.entity.monster.Strider) this.entity; + } + @Override public boolean isShivering() { return this.getHandle().isSuffocating(); @@ -67,14 +72,4 @@ public class CraftStrider extends CraftAnimals implements Strider { public Material getSteerMaterial() { return Material.WARPED_FUNGUS_ON_A_STICK; } - - @Override - public net.minecraft.world.entity.monster.Strider getHandle() { - return (net.minecraft.world.entity.monster.Strider) this.entity; - } - - @Override - public String toString() { - return "CraftStrider"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java index 465edd85d..eea78db7f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java @@ -12,6 +12,11 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { super(server, entity); } + @Override + public PrimedTnt getHandle() { + return (PrimedTnt) this.entity; + } + @Override public float getYield() { return this.getHandle().explosionPower; @@ -42,16 +47,6 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { this.getHandle().setFuse(fuseTicks); } - @Override - public PrimedTnt getHandle() { - return (PrimedTnt) this.entity; - } - - @Override - public String toString() { - return "CraftTNTPrimed"; - } - @Override public Entity getSource() { net.minecraft.world.entity.LivingEntity source = this.getHandle().getOwner(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTadpole.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTadpole.java index 18001eae9..1efb6f720 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTadpole.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTadpole.java @@ -14,11 +14,6 @@ public class CraftTadpole extends CraftFish implements org.bukkit.entity.Tadpole return (Tadpole) this.entity; } - @Override - public String toString() { - return "CraftTadpole"; - } - @Override public int getAge() { return this.getHandle().age; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java index d2555af89..d41b159e3 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java @@ -10,13 +10,14 @@ import org.bukkit.entity.Creature; import org.bukkit.entity.Tameable; public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creature { + public CraftTameableAnimal(CraftServer server, TamableAnimal entity) { super(server, entity); } @Override public TamableAnimal getHandle() { - return (TamableAnimal) super.getHandle(); + return (TamableAnimal) this.entity; } @Override @@ -79,9 +80,4 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat this.getHandle().setInSittingPose(sitting); this.getHandle().setOrderedToSit(sitting); } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "{owner=" + this.getOwner() + ",tamed=" + this.isTamed() + "}"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTextDisplay.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTextDisplay.java index 580e4f77d..36b40c847 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTextDisplay.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTextDisplay.java @@ -15,12 +15,7 @@ public class CraftTextDisplay extends CraftDisplay implements TextDisplay { @Override public net.minecraft.world.entity.Display.TextDisplay getHandle() { - return (net.minecraft.world.entity.Display.TextDisplay) super.getHandle(); - } - - @Override - public String toString() { - return "CraftTextDisplay"; + return (net.minecraft.world.entity.Display.TextDisplay) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrowableProjectile.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrowableProjectile.java index 5c660de48..f34b81ac5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrowableProjectile.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrowableProjectile.java @@ -12,6 +12,11 @@ public abstract class CraftThrowableProjectile extends CraftProjectile implement super(server, entity); } + @Override + public ThrowableItemProjectile getHandle() { + return (ThrowableItemProjectile) this.entity; + } + @Override public ItemStack getItem() { if (this.getHandle().getItem().isEmpty()) { @@ -25,9 +30,4 @@ public abstract class CraftThrowableProjectile extends CraftProjectile implement public void setItem(ItemStack item) { this.getHandle().setItem(CraftItemStack.asNMSCopy(item)); } - - @Override - public ThrowableItemProjectile getHandle() { - return (ThrowableItemProjectile) this.entity; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java index 5e7fef664..9e4b55545 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java @@ -5,6 +5,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.ThrownExpBottle; public class CraftThrownExpBottle extends CraftThrowableProjectile implements ThrownExpBottle { + public CraftThrownExpBottle(CraftServer server, ThrownExperienceBottle entity) { super(server, entity); } @@ -13,9 +14,4 @@ public class CraftThrownExpBottle extends CraftThrowableProjectile implements Th public ThrownExperienceBottle getHandle() { return (ThrownExperienceBottle) this.entity; } - - @Override - public String toString() { - return "EntityThrownExpBottle"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownLingeringPotion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownLingeringPotion.java index 67db3c421..8be9f6988 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownLingeringPotion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownLingeringPotion.java @@ -16,6 +16,11 @@ public class CraftThrownLingeringPotion extends CraftThrownPotion implements Lin super(server, entity); } + @Override + public ThrownLingeringPotion getHandle() { + return (ThrownLingeringPotion) this.entity; + } + @Override public void setItem(final ItemStack item) { Preconditions.checkArgument(item != null, "ItemStack cannot be null"); @@ -30,9 +35,4 @@ public class CraftThrownLingeringPotion extends CraftThrownPotion implements Lin public PotionMeta getPotionMeta() { return (PotionMeta) CraftItemStack.getItemMeta(this.getHandle().getItem(), ItemType.LINGERING_POTION); } - - @Override - public ThrownLingeringPotion getHandle() { - return (ThrownLingeringPotion) this.entity; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java index 7927b8c04..61becdf5c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java @@ -19,6 +19,11 @@ public abstract class CraftThrownPotion extends CraftThrowableProjectile impleme super(server, entity); } + @Override + public AbstractThrownPotion getHandle() { + return (AbstractThrownPotion) this.entity; + } + @Override public Collection getEffects() { ImmutableList.Builder builder = ImmutableList.builder(); @@ -44,9 +49,4 @@ public abstract class CraftThrownPotion extends CraftThrowableProjectile impleme public void splash() { this.getHandle().splash(null); } - - @Override - public AbstractThrownPotion getHandle() { - return (AbstractThrownPotion) this.entity; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownSplashPotion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownSplashPotion.java index 42c7f16ef..8e7078878 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownSplashPotion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownSplashPotion.java @@ -16,6 +16,11 @@ public class CraftThrownSplashPotion extends CraftThrownPotion implements Splash super(server, entity); } + @Override + public ThrownSplashPotion getHandle() { + return (ThrownSplashPotion) this.entity; + } + @Override public void setItem(final ItemStack item) { Preconditions.checkArgument(item != null, "ItemStack cannot be null"); @@ -30,9 +35,4 @@ public class CraftThrownSplashPotion extends CraftThrownPotion implements Splash public PotionMeta getPotionMeta() { return (PotionMeta) CraftItemStack.getItemMeta(this.getHandle().getItem(), ItemType.SPLASH_POTION); } - - @Override - public ThrownSplashPotion getHandle() { - return (ThrownSplashPotion) this.entity; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java index 4b3a76411..174332208 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTraderLlama.java @@ -11,11 +11,6 @@ public class CraftTraderLlama extends CraftLlama implements TraderLlama { @Override public net.minecraft.world.entity.animal.horse.TraderLlama getHandle() { - return (net.minecraft.world.entity.animal.horse.TraderLlama) super.getHandle(); - } - - @Override - public String toString() { - return "CraftTraderLlama"; + return (net.minecraft.world.entity.animal.horse.TraderLlama) this.entity; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java index 3e34efebc..6d4f7d516 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java @@ -14,7 +14,7 @@ public class CraftTrident extends CraftAbstractArrow implements Trident { @Override public ThrownTrident getHandle() { - return (ThrownTrident) super.getHandle(); + return (ThrownTrident) this.entity; } @Override @@ -27,11 +27,6 @@ public class CraftTrident extends CraftAbstractArrow implements Trident { this.getHandle().pickupItemStack = CraftItemStack.asNMSCopy(itemStack); } - @Override - public String toString() { - return "CraftTrident"; - } - @Override public boolean hasGlint() { return this.getHandle().isFoil(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTropicalFish.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTropicalFish.java index 238ab5c01..6ec2e173c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTropicalFish.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTropicalFish.java @@ -15,11 +15,6 @@ public class CraftTropicalFish extends io.papermc.paper.entity.PaperSchoolableFi return (net.minecraft.world.entity.animal.TropicalFish) this.entity; } - @Override - public String toString() { - return "CraftTropicalFish"; - } - @Override public DyeColor getPatternColor() { return CraftTropicalFish.getPatternColor(this.getHandle().getPackedVariant()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java index f8335d9ed..3aae36e3b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java @@ -12,12 +12,7 @@ public class CraftTurtle extends CraftAnimals implements Turtle { @Override public net.minecraft.world.entity.animal.Turtle getHandle() { - return (net.minecraft.world.entity.animal.Turtle) super.getHandle(); - } - - @Override - public String toString() { - return "CraftTurtle"; + return (net.minecraft.world.entity.animal.Turtle) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java index 59e5b417e..d58b163bf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java @@ -4,12 +4,8 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Vehicle; public abstract class CraftVehicle extends CraftEntity implements Vehicle { + public CraftVehicle(CraftServer server, net.minecraft.world.entity.Entity entity) { super(server, entity); } - - @Override - public String toString() { - return "CraftVehicle{passenger=" + this.getPassenger() + '}'; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java index 23a469ba8..227640d34 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java @@ -15,7 +15,7 @@ public class CraftVex extends CraftMonster implements Vex { @Override public net.minecraft.world.entity.monster.Vex getHandle() { - return (net.minecraft.world.entity.monster.Vex) super.getHandle(); + return (net.minecraft.world.entity.monster.Vex) this.entity; } @Override @@ -49,11 +49,6 @@ public class CraftVex extends CraftMonster implements Vex { this.getHandle().limitedLifeTicks = ticks; } - @Override - public String toString() { - return "CraftVex"; - } - @Override public boolean isCharging() { return this.getHandle().isCharging(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java index 196e64467..258e149a4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -35,11 +35,6 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { return (net.minecraft.world.entity.npc.Villager) this.entity; } - @Override - public String toString() { - return "CraftVillager"; - } - @Override public void remove() { this.getHandle().releaseAllPois(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java index 835932993..c09a3e065 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillagerZombie.java @@ -16,12 +16,7 @@ public class CraftVillagerZombie extends CraftZombie implements ZombieVillager { @Override public net.minecraft.world.entity.monster.ZombieVillager getHandle() { - return (net.minecraft.world.entity.monster.ZombieVillager) super.getHandle(); - } - - @Override - public String toString() { - return "CraftVillagerZombie"; + return (net.minecraft.world.entity.monster.ZombieVillager) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java index bcd3370bc..4207a1cd7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVindicator.java @@ -11,12 +11,7 @@ public class CraftVindicator extends CraftIllager implements Vindicator { @Override public net.minecraft.world.entity.monster.Vindicator getHandle() { - return (net.minecraft.world.entity.monster.Vindicator) super.getHandle(); - } - - @Override - public String toString() { - return "CraftVindicator"; + return (net.minecraft.world.entity.monster.Vindicator) this.entity; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java index 657b45017..e698cbf4f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java @@ -15,11 +15,6 @@ public class CraftWanderingTrader extends CraftAbstractVillager implements Wande return (net.minecraft.world.entity.npc.WanderingTrader) this.entity; } - @Override - public String toString() { - return "CraftWanderingTrader"; - } - @Override public int getDespawnDelay() { return this.getHandle().getDespawnDelay(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java index f27f2812f..7a8f524e0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java @@ -20,11 +20,6 @@ public class CraftWarden extends CraftMonster implements org.bukkit.entity.Warde return (Warden) this.entity; } - @Override - public String toString() { - return "CraftWarden"; - } - @Override public int getAnger() { return this.getHandle().getAngerManagement().getActiveAnger(this.getHandle().getTarget()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java index 1b347deb6..be249743c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java @@ -14,9 +14,4 @@ public class CraftWaterMob extends CraftCreature implements WaterMob { public WaterAnimal getHandle() { return (WaterAnimal) this.entity; } - - @Override - public String toString() { - return "CraftWaterMob"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java index 46447b965..bb3301ff6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWindCharge.java @@ -4,6 +4,7 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.WindCharge; public class CraftWindCharge extends CraftAbstractWindCharge implements WindCharge { + public CraftWindCharge(CraftServer server, net.minecraft.world.entity.projectile.windcharge.WindCharge entity) { super(server, entity); } @@ -12,9 +13,4 @@ public class CraftWindCharge extends CraftAbstractWindCharge implements WindChar public net.minecraft.world.entity.projectile.windcharge.WindCharge getHandle() { return (net.minecraft.world.entity.projectile.windcharge.WindCharge) this.entity; } - - @Override - public String toString() { - return "CraftWindCharge"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java index ab86a8c85..007a11e4d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java @@ -1,13 +1,14 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import org.bukkit.Material; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Witch; -import org.bukkit.Material; import org.bukkit.inventory.ItemStack; public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.paper.entity.CraftRangedEntity { // Paper + public CraftWitch(CraftServer server, net.minecraft.world.entity.monster.Witch entity) { super(server, entity); } @@ -17,11 +18,6 @@ public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo. return (net.minecraft.world.entity.monster.Witch) this.entity; } - @Override - public String toString() { - return "CraftWitch"; - } - @Override public boolean isDrinkingPotion() { return this.getHandle().isDrinkingPotion(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java index 51383cd06..2e11df97e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java @@ -26,11 +26,6 @@ public class CraftWither extends CraftMonster implements Wither, com.destroystok return (WitherBoss) this.entity; } - @Override - public String toString() { - return "CraftWither"; - } - @Override public BossBar getBossBar() { return this.bossBar; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkeleton.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkeleton.java index ffee517b2..79eee4222 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkeleton.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkeleton.java @@ -10,11 +10,6 @@ public class CraftWitherSkeleton extends CraftAbstractSkeleton implements Wither super(server, entity); } - @Override - public String toString() { - return "CraftWitherSkeleton"; - } - @Override public SkeletonType getSkeletonType() { return SkeletonType.WITHER; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java index bc9783912..027849368 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java @@ -4,10 +4,16 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.WitherSkull; public class CraftWitherSkull extends CraftFireball implements WitherSkull { + public CraftWitherSkull(CraftServer server, net.minecraft.world.entity.projectile.WitherSkull entity) { super(server, entity); } + @Override + public net.minecraft.world.entity.projectile.WitherSkull getHandle() { + return (net.minecraft.world.entity.projectile.WitherSkull) this.entity; + } + @Override public void setCharged(boolean charged) { this.getHandle().setDangerous(charged); @@ -17,14 +23,4 @@ public class CraftWitherSkull extends CraftFireball implements WitherSkull { public boolean isCharged() { return this.getHandle().isDangerous(); } - - @Override - public net.minecraft.world.entity.projectile.WitherSkull getHandle() { - return (net.minecraft.world.entity.projectile.WitherSkull) this.entity; - } - - @Override - public String toString() { - return "CraftWitherSkull"; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java index b9cd648b2..c3bd4cc14 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java @@ -13,10 +13,16 @@ import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.entity.Wolf; public class CraftWolf extends CraftTameableAnimal implements Wolf { + public CraftWolf(CraftServer server, net.minecraft.world.entity.animal.wolf.Wolf wolf) { super(server, wolf); } + @Override + public net.minecraft.world.entity.animal.wolf.Wolf getHandle() { + return (net.minecraft.world.entity.animal.wolf.Wolf) this.entity; + } + @Override public boolean isAngry() { return this.getHandle().isAngry(); @@ -31,11 +37,6 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { } } - @Override - public net.minecraft.world.entity.animal.wolf.Wolf getHandle() { - return (net.minecraft.world.entity.animal.wolf.Wolf) this.entity; - } - @Override public DyeColor getCollarColor() { return DyeColor.getByWoolData((byte) this.getHandle().getCollarColor().getId()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZoglin.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZoglin.java index c134c4bb8..583af9561 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZoglin.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZoglin.java @@ -9,6 +9,11 @@ public class CraftZoglin extends CraftMonster implements Zoglin { super(server, entity); } + @Override + public net.minecraft.world.entity.monster.Zoglin getHandle() { + return (net.minecraft.world.entity.monster.Zoglin) this.entity; + } + @Override public boolean isBaby() { return this.getHandle().isBaby(); @@ -19,16 +24,6 @@ public class CraftZoglin extends CraftMonster implements Zoglin { this.getHandle().setBaby(flag); } - @Override - public net.minecraft.world.entity.monster.Zoglin getHandle() { - return (net.minecraft.world.entity.monster.Zoglin) this.entity; - } - - @Override - public String toString() { - return "CraftZoglin"; - } - @Override public int getAge() { return this.getHandle().isBaby() ? -1 : 0; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java index ec0869363..9851c3890 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java @@ -17,11 +17,6 @@ public class CraftZombie extends CraftMonster implements Zombie { return (net.minecraft.world.entity.monster.Zombie) this.entity; } - @Override - public String toString() { - return "CraftZombie"; - } - @Override public boolean isBaby() { return this.getHandle().isBaby(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombieHorse.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombieHorse.java index 2c47ea42d..1b3b52a54 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombieHorse.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombieHorse.java @@ -10,11 +10,6 @@ public class CraftZombieHorse extends CraftAbstractHorse implements ZombieHorse super(server, entity); } - @Override - public String toString() { - return "CraftZombieHorse"; - } - @Override public Variant getVariant() { return Variant.UNDEAD_HORSE; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index a7e3afe04..9774c9c72 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -878,10 +878,10 @@ public class CraftEventFactory { return event; } - public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior + public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean showDeathMessages, boolean keepInventory) { CraftPlayer entity = victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); - PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior + PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage, showDeathMessages); event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable @@ -1961,6 +1961,9 @@ public class CraftEventFactory { return; } + // Do not call during generation. + if (entity.generation) return; + Bukkit.getPluginManager().callEvent(new EntityRemoveEvent(entity.getBukkitEntity(), cause)); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java b/paper-server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java index bd5b968e8..70b45a7d4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java @@ -199,18 +199,15 @@ public class SimpleHelpMap implements HelpMap { } private String getCommandPluginName(Command command) { - // Paper start - Move up if (command instanceof PluginIdentifiableCommand) { return ((PluginIdentifiableCommand) command).getPlugin().getName(); } - // Paper end - if (command instanceof VanillaCommandWrapper) { - return "Minecraft"; + if (command instanceof VanillaCommandWrapper wrapper) { + return wrapper.helpCommandNamespace; } if (command instanceof BukkitCommand) { return "Bukkit"; } - // Paper - Move PluginIdentifiableCommand instanceof check to allow brig commands return null; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java index 1ce328bed..c00ddfe41 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -95,6 +95,11 @@ public class CraftContainer extends AbstractContainerMenu { this.title = title; } + @Override + public MenuType getMenuType() { + return CraftMenuType.minecraftToBukkit(getNotchInventoryType(inventory)); + } + }, player, id); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java index e9fd57b9e..5039d87d7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java @@ -94,6 +94,12 @@ public class CraftInventoryView menuType = container.menuType; + return menuType != null ? CraftMenuType.minecraftToBukkit(menuType) : null; + } + public boolean isInTop(int rawSlot) { return rawSlot < this.viewing.getSize(); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 978836a87..753795106 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -214,9 +214,9 @@ public final class CraftItemFactory implements ItemFactory { return CraftItemStack.asCraftMirror(EnchantmentHelper.enchantItem(source, craft.handle, level, registry, optional)); } - // Paper start - Adventure @Override public net.kyori.adventure.text.event.HoverEvent asHoverEvent(final ItemStack item, final java.util.function.UnaryOperator op) { + Preconditions.checkArgument(item.getAmount() > 0 && item.getAmount() <= Item.ABSOLUTE_MAX_STACK_SIZE, "ItemStack amount must be between 1 and %s but was %s", Item.ABSOLUTE_MAX_STACK_SIZE, item.getAmount()); return net.kyori.adventure.text.event.HoverEvent.showItem(op.apply( net.kyori.adventure.text.event.HoverEvent.ShowItem.showItem( item.getType().getKey(), @@ -229,7 +229,6 @@ public final class CraftItemFactory implements ItemFactory { public net.kyori.adventure.text.@org.jetbrains.annotations.NotNull Component displayName(@org.jetbrains.annotations.NotNull ItemStack itemStack) { return io.papermc.paper.adventure.PaperAdventure.asAdventure(CraftItemStack.asNMSCopy(itemStack).getDisplayName()); } - // Paper end - Adventure // Paper start - ensure server conversions API // TODO: DO WE NEED THIS? diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index 1aa17423f..02109a3ca 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -268,15 +268,13 @@ public final class CraftItemStack extends ItemStack { public void addUnsafeEnchantment(Enchantment enchant, int level) { Preconditions.checkArgument(enchant != null, "Enchantment cannot be null"); - // Paper start if (this.handle == null) { return; } EnchantmentHelper.updateEnchantments(this.handle, mutable -> { // data component api doesn't really support mutable things once already set yet mutable.set(CraftEnchantment.bukkitToMinecraftHolder(enchant), level); - }); - // Paper end + }, true); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java index ea7335e32..75fa6f99c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMerchantCustom.java @@ -33,11 +33,6 @@ public class CraftMerchantCustom implements CraftMerchant { } // Paper end - @Override - public String toString() { - return "CraftMerchantCustom"; - } - @Override public MinecraftMerchant getMerchant() { return this.merchant; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java index a3d3ea247..05db0af60 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.inventory; import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap.Builder; import java.util.ArrayList; @@ -25,6 +26,7 @@ import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; +import org.jetbrains.annotations.NotNull; @DelegateDeserialization(SerializableMeta.class) class CraftMetaPotion extends CraftMetaItem implements PotionMeta { @@ -202,6 +204,19 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { return ImmutableList.of(); } + @Override + @NotNull + public List getAllEffects() { + final ImmutableList.Builder builder = ImmutableList.builder(); + if (this.hasBasePotionType()) { + builder.addAll(this.getBasePotionType().getPotionEffects()); + } + if (this.hasCustomEffects()) { + builder.addAll(this.customEffects); + } + return builder.build(); + } + @Override public boolean addCustomEffect(PotionEffect effect, boolean overwrite) { Preconditions.checkArgument(effect != null, "Potion effect cannot be null"); @@ -305,6 +320,17 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { this.color = color == null ? null : color.asRGB(); } + @Override + @NotNull + public Color computeEffectiveColor() { + if (hasColor()) return getColor(); + + return Color.fromRGB( + PotionContents.getColorOptional(Collections2.transform(getAllEffects(), CraftPotionUtil::fromBukkit)) + .orElse(PotionContents.BASE_POTION_COLOR) & 0xFFFFFF + ); + } + @Override public boolean hasCustomPotionName() { return this.customName != null; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java b/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java index 1ca99a7a0..816c81007 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java @@ -64,7 +64,7 @@ public class CraftMapCanvas implements MapCanvas { return; if (this.buffer[y * 128 + x] != color) { this.buffer[y * 128 + x] = color; - this.mapView.worldMap.setColorsDirty(x, y); + this.mapView.worldMap.setColorsDirty(x, y, false); // Paper - Fix unnecessary map data saves } } @@ -141,8 +141,8 @@ public class CraftMapCanvas implements MapCanvas { } // Mark all colors within the image as dirty - this.mapView.worldMap.setColorsDirty(destX, destY); - this.mapView.worldMap.setColorsDirty(destX + effectiveWidth - 1, destY + effectiveHeight - 1); + this.mapView.worldMap.setColorsDirty(destX, destY, false); + this.mapView.worldMap.setColorsDirty(destX + effectiveWidth - 1, destY + effectiveHeight - 1, false); // Paper end } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index f78cfd9c0..a287ad5cc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -551,6 +551,7 @@ public final class CraftMagicNumbers implements UnsafeValues { return ret; } + private static final TagParser SNBT_REGISTRY_UNAWARE_PARSER = TagParser.create(NbtOps.INSTANCE); @Override public @org.jetbrains.annotations.NotNull ItemStack deserializeStack(@org.jetbrains.annotations.NotNull final Map args) { final int version = args.getOrDefault("schema_version", 1) instanceof Number val ? val.intValue() : -1; @@ -581,7 +582,7 @@ public final class CraftMagicNumbers implements UnsafeValues { componentMap.forEach((componentKey, componentString) -> { final Tag componentTag; try { - componentTag = TagParser.create(NbtOps.INSTANCE).parseFully(componentString); + componentTag = SNBT_REGISTRY_UNAWARE_PARSER.parseFully(componentString); } catch (final CommandSyntaxException e) { throw new RuntimeException("Error parsing item stack data components", e); } diff --git a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java index 471941a5b..c77748061 100644 --- a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java +++ b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java @@ -109,7 +109,7 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre logger.log(Level.SEVERE, "------------------------------"); logger.log(Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):"); // Paper FeatureHooks.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - log detailed tick information - WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE), logger); + WatchdogThread.dumpThread(ManagementFactory.getThreadMXBean().getThreadInfo(MinecraftServer.getServer().serverThread.threadId(), Integer.MAX_VALUE), logger); logger.log(Level.SEVERE, "------------------------------"); // Paper start - Only print full dump on long timeouts diff --git a/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridge b/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridge new file mode 100644 index 000000000..02e0ef064 --- /dev/null +++ b/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridge @@ -0,0 +1 @@ +io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridgeImpl