From bdfad1c838968996b39093c7dae3877a55252724 Mon Sep 17 00:00:00 2001 From: powercas_gamer Date: Wed, 1 Jan 2025 01:47:57 +0100 Subject: [PATCH 001/203] Add sendRich/PlainMessage methods to Server (#11872) --- .../src/main/java/org/bukkit/Server.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index e47e482d7..041ebeb28 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -14,6 +14,9 @@ import java.util.Set; import java.util.UUID; import java.util.function.Consumer; import java.util.logging.Logger; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.Warning.WarningState; import org.bukkit.advancement.Advancement; import org.bukkit.block.data.BlockData; @@ -409,6 +412,40 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi } // Paper end + /** + * Sends a message with the MiniMessage format to the server. + *

+ * See MiniMessage docs + * for more information on the format. + * + * @param message MiniMessage content + */ + default void sendRichMessage(final @NotNull String message) { + this.sendMessage(MiniMessage.miniMessage().deserialize(message)); + } + + /** + * Sends a message with the MiniMessage format to the server. + *

+ * See MiniMessage docs and MiniMessage Placeholders docs + * for more information on the format. + * + * @param message MiniMessage content + * @param resolvers resolvers to use + */ + default void sendRichMessage(final @NotNull String message, final @NotNull TagResolver... resolvers) { + this.sendMessage(MiniMessage.miniMessage().deserialize(message, resolvers)); + } + + /** + * Sends a plain message to the server. + * + * @param message plain message + */ + default void sendPlainMessage(final @NotNull String message) { + this.sendMessage(Component.text(message)); + } + /** * Gets the name of the update folder. The update folder is used to safely * update plugins at the right moment on a plugin load. From 1dd52bed4990980e1112e9cc205b95fb768721c8 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Wed, 1 Jan 2025 18:53:23 +0100 Subject: [PATCH 002/203] Use playerlist whitelist status instead of properties The actual property value is final, only the serialized output is changed. This uses the correct value from PlayerList instead Fixes #11878 --- .../sources/net/minecraft/server/MinecraftServer.java.patch | 5 +++-- .../src/main/java/org/bukkit/craftbukkit/CraftServer.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch index a56079b3c..6009edbd8 100644 --- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -1262,11 +1262,12 @@ } } -@@ -1652,10 +_,11 @@ +@@ -1651,11 +_,12 @@ + public void kickUnlistedPlayers(CommandSourceStack commandSource) { if (this.isEnforceWhitelist()) { PlayerList playerList = commandSource.getServer().getPlayerList(); ++ if (!playerList.isUsingWhitelist()) return; // Paper - whitelist not enabled UserWhiteList whiteList = playerList.getWhiteList(); -+ if (!((net.minecraft.server.dedicated.DedicatedServer) this).getProperties().whiteList.get()) return; // Paper - whitelist not enabled for (ServerPlayer serverPlayer : Lists.newArrayList(playerList.getPlayers())) { - if (!whiteList.isWhiteListed(serverPlayer.getGameProfile())) { 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 f59b4a699..381448d8e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -883,7 +883,7 @@ public final class CraftServer implements Server { @Override public boolean hasWhitelist() { - return this.getProperties().whiteList.get(); + return this.playerList.isUsingWhitelist(); } // NOTE: Temporary calls through to server.properies until its replaced From 83995d7e805a2ca55fc5031dc5dffc24a6d38b02 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Wed, 1 Jan 2025 21:56:23 +0100 Subject: [PATCH 003/203] Fix settings changes not being saved (#11881) Closes #11878 --- .../sources/net/minecraft/server/dedicated/Settings.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/Settings.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/Settings.java.patch index b690197c4..26a7bec38 100644 --- a/paper-server/patches/sources/net/minecraft/server/dedicated/Settings.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/dedicated/Settings.java.patch @@ -122,7 +122,7 @@ Properties map = Settings.this.cloneProperties(); map.put(this.key, this.serializer.apply(newValue)); - return Settings.this.reload(registryAccess, map); -+ return Settings.this.reload(registryAccess, properties, Settings.this.options); // CraftBukkit ++ return Settings.this.reload(registryAccess, map, Settings.this.options); // CraftBukkit } } } From daddcf67420e92ce1eba27949f3c847a92ffab14 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Thu, 2 Jan 2025 09:15:47 +0100 Subject: [PATCH 004/203] Fix JOML javadoc URL (#11883) --- paper-api/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-api/build.gradle.kts b/paper-api/build.gradle.kts index 9da148e36..8b5d559a9 100644 --- a/paper-api/build.gradle.kts +++ b/paper-api/build.gradle.kts @@ -176,7 +176,7 @@ tasks.withType { "https://guava.dev/releases/33.3.1-jre/api/docs/", "https://javadoc.io/doc/org.yaml/snakeyaml/2.2/", "https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/", - "https://javadoc.io/doc/org.joml/joml/1.10.8/index.html", + "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/$adventureVersion/", From edde7264c6f422203194d155c6a0983091258cbe Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:22:20 -0300 Subject: [PATCH 005/203] [ci skip] Add missing Nullable annotations for NMS DamageSource (#11875) --- .../world/damagesource/DamageSource.java.patch | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch index 44ed121c0..00eaac621 100644 --- a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/damagesource/DamageSource.java +++ b/net/minecraft/world/damagesource/DamageSource.java -@@ -20,6 +_,105 @@ +@@ -20,6 +_,107 @@ private final Entity directEntity; @Nullable private final Vec3 damageSourcePosition; @@ -58,18 +58,19 @@ + return damageSource; + } + ++ @Nullable + public org.bukkit.block.Block getDirectBlock() { + return this.directBlock; + } + -+ public DamageSource directBlock(net.minecraft.world.level.Level world, net.minecraft.core.BlockPos blockPosition) { ++ public DamageSource directBlock(@Nullable net.minecraft.world.level.Level world, @Nullable net.minecraft.core.BlockPos blockPosition) { + if (blockPosition == null || world == null) { + return this; + } + return this.directBlock(org.bukkit.craftbukkit.block.CraftBlock.at(world, blockPosition)); + } + -+ public DamageSource directBlock(org.bukkit.block.Block block) { ++ public DamageSource directBlock(@Nullable org.bukkit.block.Block block) { + if (block == null) { + return this; + } @@ -79,11 +80,12 @@ + return damageSource; + } + ++ @Nullable + public org.bukkit.block.BlockState getDirectBlockState() { + return this.directBlockState; + } + -+ public DamageSource directBlockState(org.bukkit.block.BlockState blockState) { ++ public DamageSource directBlockState(@Nullable org.bukkit.block.BlockState blockState) { + if (blockState == null) { + return this; + } From 4106da712cf1e07c3916ec4dc5d8077253a298cc Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Sat, 4 Jan 2025 12:19:07 -0800 Subject: [PATCH 006/203] Fix retain passengers teleport flag (#11858) --- build-data/paper.at | 1 + .../java/org/bukkit/craftbukkit/entity/CraftEntity.java | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build-data/paper.at b/build-data/paper.at index 47ca2bb35..bb447c721 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -196,6 +196,7 @@ public net.minecraft.world.entity.Entity random public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V public net.minecraft.world.entity.Entity setRot(FF)V public net.minecraft.world.entity.Entity setSharedFlag(IZ)V +public net.minecraft.world.entity.Entity teleportPassengers()V public net.minecraft.world.entity.Entity unsetRemoved()V public net.minecraft.world.entity.Entity wasTouchingWater public net.minecraft.world.entity.ExperienceOrb count 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 86388f04b..4562bee2e 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 @@ -245,7 +245,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Paper start - Teleport passenger API Set flagSet = Set.of(flags); boolean dismount = !flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE); - boolean ignorePassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS); + boolean retainPassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS); // Don't allow teleporting between worlds while keeping passengers if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) { return false; @@ -257,7 +257,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } // Paper end - if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API + if ((!retainPassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API return false; } @@ -288,6 +288,9 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // SPIGOT-619: Force sync head rotation also this.entity.setYHeadRot(location.getYaw()); + // Ensure passengers of entity are teleported + if (retainPassengers && this.entity.isVehicle()) this.entity.teleportPassengers(); + return true; } From 6ab13521b7dc94469b9b6fcc01164345144de375 Mon Sep 17 00:00:00 2001 From: ChromMob <62996347+ChromMob@users.noreply.github.com> Date: Sat, 4 Jan 2025 21:23:21 +0100 Subject: [PATCH 007/203] Improve performance of PoiCompetitorScan by unrolling stream (#11871) --- .../ai/behavior/PoiCompetitorScan.java.patch | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java.patch new file mode 100644 index 000000000..abad8cfd9 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java ++++ b/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java +@@ -22,13 +_,32 @@ + level.getPoiManager() + .getType(globalPos.pos()) + .ifPresent( +- poi -> instance.>get(nearestLivingEntities) +- .stream() +- .filter(entity -> entity instanceof Villager && entity != villager) +- .map(entity -> (Villager)entity) +- .filter(LivingEntity::isAlive) +- .filter(v -> competesForSameJobsite(globalPos, poi, v)) +- .reduce(villager, PoiCompetitorScan::selectWinner) ++ // Paper start - Improve performance of PoiCompetitorScan by unrolling stream ++ // The previous logic used Stream#reduce to simulate a form of single-iteration bubble sort ++ // in which the "winning" villager would maintain MemoryModuleType.JOB_SITE while all others ++ // would lose said memory module type by passing each "current winner" and incoming next ++ // villager to #selectWinner. ++ poi -> { ++ final List livingEntities = instance.get(nearestLivingEntities); ++ ++ Villager winner = villager; ++ for (final LivingEntity other : livingEntities) { ++ if (other == villager) { ++ continue; ++ } ++ if (!(other instanceof final net.minecraft.world.entity.npc.Villager otherVillager)) { ++ continue; ++ } ++ if (!other.isAlive()) { ++ continue; ++ } ++ if (!competesForSameJobsite(globalPos, poi, otherVillager)) { ++ continue; ++ } ++ winner = selectWinner(winner, otherVillager); ++ } ++ } ++ // Paper end - Improve performance of PoiCompetitorScan by unrolling stream + ); + return true; + } From 33a590bca6461c6420156f6ea48ff27e92aec7a0 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sat, 4 Jan 2025 17:30:41 -0300 Subject: [PATCH 008/203] Fix TargetHitEvent#getSignalStrength() post-hard-fork (#11897) --- .../minecraft/world/level/block/TargetBlock.java.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch index eeb2fc28b..6ea06255f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TargetBlock.java.patch @@ -20,12 +20,12 @@ + if (projectile instanceof Projectile) { + final org.bukkit.craftbukkit.block.CraftBlock craftBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, hit.getBlockPos()); + final org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(hit.getDirection()); -+ final io.papermc.paper.event.block.TargetHitEvent targetHitEvent = new io.papermc.paper.event.block.TargetHitEvent((org.bukkit.entity.Projectile) projectile.getBukkitEntity(), craftBlock, blockFace, i); ++ final io.papermc.paper.event.block.TargetHitEvent targetHitEvent = new io.papermc.paper.event.block.TargetHitEvent((org.bukkit.entity.Projectile) projectile.getBukkitEntity(), craftBlock, blockFace, redstoneStrength); + if (targetHitEvent.callEvent()) { -+ i = targetHitEvent.getSignalStrength(); ++ redstoneStrength = targetHitEvent.getSignalStrength(); + shouldAward = true; + } else { -+ return i; ++ return redstoneStrength; + } + } + // Paper end - Add TargetHitEvent @@ -35,7 +35,7 @@ + + // Paper start - Award Hit Criteria after Block Update + if (shouldAward) { -+ awardTargetHitCriteria((Projectile) projectile, hit, i); ++ awardTargetHitCriteria((Projectile) projectile, hit, redstoneStrength); + } + // Paper end - Award Hit Criteria after Block Update From f367f107cff30e7295777f809e5d7b8d89dff42f Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sat, 4 Jan 2025 17:54:27 -0300 Subject: [PATCH 009/203] Add rotation helpers to Location (#11908) --- .../src/main/java/org/bukkit/Location.java | 99 ++++++++++++------- 1 file changed, 65 insertions(+), 34 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Location.java b/paper-api/src/main/java/org/bukkit/Location.java index bdc065a48..8bc340c9d 100644 --- a/paper-api/src/main/java/org/bukkit/Location.java +++ b/paper-api/src/main/java/org/bukkit/Location.java @@ -3,24 +3,21 @@ package org.bukkit; import com.google.common.base.Preconditions; import java.lang.ref.Reference; import java.lang.ref.WeakReference; -import com.google.common.base.Preconditions; // Paper +import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Predicate; +import io.papermc.paper.math.FinePosition; import org.bukkit.block.Block; import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.entity.Entity; // Paper -import org.bukkit.util.NumberConversions; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -// Paper start -import java.util.Collection; -import java.util.function.Predicate; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; -// Paper end +import org.bukkit.util.NumberConversions; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Represents a 3-dimensional position in a world. @@ -30,7 +27,7 @@ import org.bukkit.entity.Player; * magnitude than 360 are valid, but may be normalized to any other equivalent * representation by the implementation. */ -public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition { // Paper +public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition { private Reference world; private double x; private double y; @@ -46,7 +43,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm * @param y The y-coordinate of this new location * @param z The z-coordinate of this new location */ - public Location(@UndefinedNullability final World world, final double x, final double y, final double z) { // Paper + public Location(@UndefinedNullability final World world, final double x, final double y, final double z) { this(world, x, y, z, 0, 0); } @@ -60,7 +57,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm * @param yaw The absolute rotation on the x-plane, in degrees * @param pitch The absolute rotation on the y-plane, in degrees */ - public Location(@UndefinedNullability final World world, final double x, final double y, final double z, final float yaw, final float pitch) { // Paper + public Location(@UndefinedNullability final World world, final double x, final double y, final double z, final float yaw, final float pitch) { if (world != null) { this.world = new WeakReference<>(world); } @@ -102,7 +99,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm * @throws IllegalArgumentException when world is unloaded * @see #isWorldLoaded() */ - @UndefinedNullability // Paper + @UndefinedNullability public World getWorld() { if (this.world == null) { return null; @@ -398,6 +395,22 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } + /** + * Adds rotation in the form of yaw and patch to this location. Not world-aware. + * + * @param yaw yaw, measured in degrees. + * @param pitch pitch, measured in degrees. + * @return the same location + * @see Vector + */ + @NotNull + @Contract(value = "_,_ -> this", mutates = "this") + public Location addRotation(final float yaw, final float pitch) { + this.yaw += yaw; + this.pitch += pitch; + return this; + } + /** * Subtracts the location by another. * @@ -451,6 +464,22 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } + /** + * Subtracts rotation in the form of yaw and patch from this location. + * + * @param yaw yaw, measured in degrees. + * @param pitch pitch, measured in degrees. + * @return the same location + * @see Vector + */ + @NotNull + @Contract(value = "_,_ -> this", mutates = "this") + public Location subtractRotation(final float yaw, final float pitch) { + this.yaw -= yaw; + this.pitch -= pitch; + return this; + } + /** * Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The * value of this method is not cached and uses a costly square-root @@ -543,9 +572,10 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } - public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper + public boolean isChunkLoaded() { + return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); + } - // Paper start - isGenerated API /** * Checks if a {@link Chunk} has been generated at this location. * @@ -556,9 +586,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm Preconditions.checkNotNull(world, "Location has no world!"); return world.isChunkGenerated(locToBlock(x) >> 4, locToBlock(z) >> 4); } - // Paper end - isGenerated API - - // Paper start - expand location manipulation API /** * Sets the position of this Location and returns itself @@ -578,6 +605,23 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } + /** + * Sets the rotation of this location and returns itself. + *

+ * This mutates this object, clone first. + * + * @param yaw yaw, measured in degrees. + * @param pitch pitch, measured in degrees. + * @return self (not cloned) + */ + @NotNull + @Contract(value = "_,_ -> this", mutates = "this") + public Location setRotation(final float yaw, final float pitch) { + this.yaw = yaw; + this.pitch = pitch; + return this; + } + /** * Takes the x/y/z from base and adds the specified x/y/z to it and returns self *

@@ -609,9 +653,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm public Location subtract(@NotNull Location base, double x, double y, double z) { return this.set(base.x - x, base.y - y, base.z - z); } - // Paper end - expand location manipulation API - // Paper start - expand Location API /** * @return A new location where X/Y/Z are on the Block location (integer value of X/Y/Z) */ @@ -624,7 +666,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return blockLoc; } - // Paper start /** * @return The block key for this location's block location. * @see Block#getBlockKey(int, int, int) @@ -634,7 +675,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm public long toBlockKey() { return Block.getBlockKey(getBlockX(), getBlockY(), getBlockZ()); } - // Paper end /** * @return A new location where X/Y/Z are the center of the block @@ -647,9 +687,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm centerLoc.setZ(getBlockZ() + 0.5); return centerLoc; } - // Paper end - expand Location API - // Paper start - Add heightmap api /** * 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()) @@ -671,9 +709,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm ret.setY(this.getWorld().getHighestBlockYAt(this, heightMap)); return ret; } - // Paper end - Add heightmap api - // Paper start - Expand Explosions API /** * Creates explosion at this location with given power *

@@ -754,9 +790,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm public boolean createExplosion(@Nullable Entity source, float power, boolean setFire, boolean breakBlocks) { return this.getWorld().createExplosion(source, this, power, setFire, breakBlocks); } - // Paper end - Expand Explosions API - // Paper start - additional getNearbyEntities API /** * Returns a list of entities within a bounding box centered around a Location. *

@@ -979,7 +1013,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm } return world.getNearbyEntitiesByType(clazz, this, xRadius, yRadius, zRadius, predicate); } - // Paper end - additional getNearbyEntities API @Override public boolean equals(Object obj) { @@ -1155,7 +1188,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return pitch; } - // Paper - add Position @Override public double x() { return this.getX(); @@ -1173,12 +1205,11 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm @Override public boolean isFinite() { - return io.papermc.paper.math.FinePosition.super.isFinite() && Float.isFinite(this.getYaw()) && Float.isFinite(this.getPitch()); + return FinePosition.super.isFinite() && Float.isFinite(this.getYaw()) && Float.isFinite(this.getPitch()); } @Override public @NotNull Location toLocation(@NotNull World world) { return new Location(world, this.x(), this.y(), this.z(), this.getYaw(), this.getPitch()); } - // Paper end } From 9f90b4c324077c0a407e6f94fdf47b4fa4bb31a0 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sat, 4 Jan 2025 21:54:40 +0100 Subject: [PATCH 010/203] Fix ItemDamageEvents called for 0 damage (#11900) --- .../sources/net/minecraft/world/item/ItemStack.java.patch | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch index 2bd24dd05..141de8193 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch @@ -218,6 +218,7 @@ - public void hurtAndBreak(int damage, ServerLevel level, @Nullable ServerPlayer player, Consumer onBreak) { - int i = this.processDurabilityChange(damage, level, player); +- if (i != 0) { + public void hurtAndBreak(int damage, ServerLevel level, @Nullable LivingEntity player, Consumer onBreak) { // Paper - Add EntityDamageItemEvent + // Paper start - add force boolean overload + this.hurtAndBreak(damage, level, player, onBreak, false); @@ -227,7 +228,7 @@ + final int originalDamage = damage; // Paper - Expand PlayerItemDamageEvent + int i = this.processDurabilityChange(damage, level, player, force); // Paper + // CraftBukkit start -+ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ if (i > 0 && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent - limit to positive damage and run for player + org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), i, originalDamage); // Paper - Add EntityDamageItemEvent + event.getPlayer().getServer().getPluginManager().callEvent(event); + @@ -240,7 +241,7 @@ + + i = event.getDamage(); + // Paper start - Add EntityDamageItemEvent -+ } else if (player != null) { ++ } else if (i > 0 && player != null) { + io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), i); + if (!event.callEvent()) { + return; @@ -249,7 +250,7 @@ + // Paper end - Add EntityDamageItemEvent + } + // CraftBukkit end - if (i != 0) { ++ if (i != 0) { // Paper - Add EntityDamageItemEvent - diff on change for above event ifs. this.applyDamage(this.getDamageValue() + i, player, onBreak); } } From 486e5211054391c8672f0325a27d3cf9eb5bf0cb Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 5 Jan 2025 10:07:35 -0800 Subject: [PATCH 011/203] Re-add droped MapLike spam fix (#11917) --- .../gameevent/vibrations/VibrationSystem.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch b/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch index 36b61e1dd..a69e5d7e9 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java +++ b/net/minecraft/world/level/gameevent/vibrations/VibrationSystem.java +@@ -123,7 +_,7 @@ + public static Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + VibrationInfo.CODEC.lenientOptionalFieldOf("event").forGetter(data -> Optional.ofNullable(data.currentVibration)), +- VibrationSelector.CODEC.fieldOf("selector").forGetter(VibrationSystem.Data::getSelectionStrategy), ++ VibrationSelector.CODEC.optionalFieldOf("selector").xmap(o -> o.orElseGet(VibrationSelector::new), Optional::of).forGetter(VibrationSystem.Data::getSelectionStrategy), // Paper - fix MapLike spam for missing "selector" in 1.19.2 + ExtraCodecs.NON_NEGATIVE_INT.fieldOf("event_delay").orElse(0).forGetter(VibrationSystem.Data::getTravelTimeInTicks) + ) + .apply( @@ -214,7 +_,14 @@ return false; } else { From 337557044ee43cbf46f53575efeb94b7d7c240ad Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:54:34 +0100 Subject: [PATCH 012/203] Fix MapCanvas#drawImage (#11865) --- .../craftbukkit/map/CraftMapCanvas.java | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) 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 a5e98571d..94c0e6d74 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 @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.map; import com.google.common.base.Preconditions; import java.awt.Color; import java.awt.Image; +import java.awt.image.BufferedImage; import java.util.Arrays; import org.bukkit.map.MapCanvas; import org.bukkit.map.MapCursorCollection; @@ -92,22 +93,33 @@ public class CraftMapCanvas implements MapCanvas { @Override public void drawImage(int x, int y, Image image) { // Paper start - Reduce work done by limiting size of image and using System.arraycopy - int width = 128 - x; - int height = 128 - y; - if (image.getHeight(null) < height) - height = image.getHeight(null); + final int imageWidth = image.getWidth(null); + final int imageHeight = image.getHeight(null); + + // The source x value *may* be negative, meaning we'd need to "offset" the source image before drawing it. + final int sourceX = Math.max(-x, 0); + final int sourceY = Math.max(-y, 0); + final int destX = Math.max(x, 0); + final int destY = Math.max(y, 0); + + // The effective width/height to draw on the canvas. + final int effectiveWidth = Math.min(imageWidth - sourceX, 128 - destX); + final int effectiveHeight = Math.min(imageHeight - sourceY, 128 - destY); + + if (effectiveWidth <= 0 || effectiveHeight <= 0) + return; // Create a subimage if the image is larger than the max allowed size - java.awt.image.BufferedImage temp; - if (image.getWidth(null) >= width && image instanceof java.awt.image.BufferedImage bImage) { + BufferedImage temp; + if (imageWidth >= effectiveWidth && image instanceof BufferedImage bImage) { // If the image is larger than the max allowed size, get a subimage, otherwise use the image as is - if (image.getWidth(null) > width || image.getHeight(null) > height) { - temp = bImage.getSubimage(0, 0, width, height); + if (imageWidth > effectiveWidth || imageHeight > effectiveHeight) { + temp = bImage.getSubimage(sourceX, sourceY, effectiveWidth, effectiveHeight); } else { temp = bImage; } } else { - temp = new java.awt.image.BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_ARGB); + temp = new BufferedImage(effectiveWidth, effectiveHeight, BufferedImage.TYPE_INT_ARGB); java.awt.Graphics2D graphics = temp.createGraphics(); graphics.drawImage(image, 0, 0, null); graphics.dispose(); @@ -117,14 +129,20 @@ public class CraftMapCanvas implements MapCanvas { // Since we now control the size of the image, we can safely use System.arraycopy // If x is 0, we can just copy the entire image as width is 128 and height is <=(128-y) - if (x == 0) { - System.arraycopy(bytes, 0, this.buffer, y * 128, width * height); - return; + if (x == 0 && effectiveWidth == 128) { // This only works great if the width is 128, otherwise an empty area appears + System.arraycopy(bytes, 0, this.buffer, destY * effectiveWidth, effectiveWidth * effectiveHeight); + } else { + for (int yToCopy = 0; yToCopy < effectiveHeight; ++yToCopy) { + final int src = yToCopy * effectiveWidth; + final int dest = (destY + yToCopy) * 128 + destX; + + System.arraycopy(bytes, src, this.buffer, dest, effectiveWidth); + } } - for (int y2 = 0; y2 < height; ++y2) { - System.arraycopy(bytes, 0, this.buffer, (y + y2) * 128 + x, width); - } + // Mark all colors within the image as dirty + this.mapView.worldMap.setColorsDirty(destX, destY); + this.mapView.worldMap.setColorsDirty(destX + effectiveWidth - 1, destY + effectiveHeight - 1); // Paper end } From 49d15f6345b59b2085ded0a634336d3406d62fdc Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:40:45 +0100 Subject: [PATCH 013/203] Fix DiscoveredDatapack#getSource (#11928) --- .../java/io/papermc/paper/datapack/PaperDiscoveredDatapack.java | 2 +- .../main/resources/data/minecraft/datapacks/paper/pack.mcmeta | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/datapack/PaperDiscoveredDatapack.java b/paper-server/src/main/java/io/papermc/paper/datapack/PaperDiscoveredDatapack.java index a9c7f117d..acb0701aa 100644 --- a/paper-server/src/main/java/io/papermc/paper/datapack/PaperDiscoveredDatapack.java +++ b/paper-server/src/main/java/io/papermc/paper/datapack/PaperDiscoveredDatapack.java @@ -64,6 +64,6 @@ public class PaperDiscoveredDatapack implements DiscoveredDatapack { @Override public DatapackSource getSource() { - return PACK_SOURCES.computeIfAbsent(this.pack.location().source(), source -> new DatapackSourceImpl(source.toString())); + return PACK_SOURCES.get(this.pack.location().source()); } } diff --git a/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta b/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta index 288fbe68c..dacc63ab6 100644 --- a/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta +++ b/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "Built-in Paper Datapack", - "pack_format": 41 + "pack_format": 61 } } From b34ae4fb3c01bce93f82f5d2095e1394722262e6 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 8 Jan 2025 21:46:58 +0100 Subject: [PATCH 014/203] Fix wolves ignoring result of damage event (#11932) --- .../sources/net/minecraft/world/entity/animal/Wolf.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch index 6bcb88fa1..6df46dcff 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Wolf.java.patch @@ -19,7 +19,7 @@ + public boolean actuallyHurt(ServerLevel level, DamageSource damageSource, float amount, org.bukkit.event.entity.EntityDamageEvent event) { // CraftBukkit - void -> boolean if (!this.canArmorAbsorb(damageSource)) { - super.actuallyHurt(level, damageSource, amount); -+ super.actuallyHurt(level, damageSource, amount, event); // CraftBukkit ++ return super.actuallyHurt(level, damageSource, amount, event); // CraftBukkit } else { + if (event.isCancelled()) return false; // CraftBukkit - SPIGOT-7815: if the damage was cancelled, no need to run the wolf armor behaviour ItemStack bodyArmorItem = this.getBodyArmorItem(); From efdcaa25eecadb0b573bc9f6bb571ee8c47fb46b Mon Sep 17 00:00:00 2001 From: Isaac - The456 Date: Thu, 9 Jan 2025 17:44:50 +0000 Subject: [PATCH 015/203] Fix removing the "LootTable" nbt tag from Block entities (#11929) This bug affects vanilla, and was reported as MC-279196 --- .../net/minecraft/world/RandomizableContainer.java.patch | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch index 8467c8664..1f4c7b850 100644 --- a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch @@ -9,7 +9,7 @@ this.setLootTable(lootTable); this.setLootTableSeed(seed); } -@@ -50,14 +_,15 @@ +@@ -50,15 +_,17 @@ default boolean tryLoadLootTable(CompoundTag tag) { if (tag.contains("LootTable", 8)) { @@ -25,8 +25,10 @@ - return true; + return this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish } else { ++ setLootTable(null); // Paper - Fix removing loottable from nbt not updating block entity, MC-279196 return false; } + } @@ -69,26 +_,42 @@ return false; } else { From 55f3f280cba95adc35e3783d4371a40890825b8d Mon Sep 17 00:00:00 2001 From: Owen <23108066+Owen1212055@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:58:18 -0500 Subject: [PATCH 016/203] Reimplement ItemStack Obfuscation (#11817) Reimplementation of the itemstack obfuscation config that leverages the component patch map codec to drop unwanted components on items or replaces them with sanitized versions. Co-authored-by: Bjarne Koll Co-authored-by: Jake Potrebic --- .../component/DataComponentPatch.java.patch | 29 ++++ .../core/component/DataComponents.java.patch | 6 +- .../ClientboundSetEntityDataPacket.java.patch | 2 +- .../ClientboundSetEquipmentPacket.java.patch | 2 +- .../minecraft/world/item/ItemStack.java.patch | 5 +- .../paper/configuration/Configurations.java | 8 +- .../configuration/GlobalConfiguration.java | 44 +++++- .../configuration/PaperConfigurations.java | 18 ++- .../configuration/WorldConfiguration.java | 11 -- .../ResourceLocationSerializer.java | 26 ++++ .../paper/util/ItemComponentSanitizer.java | 98 +++++++++++++ .../paper/util/ItemObfuscationBinding.java | 133 ++++++++++++++++++ .../paper/util/ItemObfuscationSession.java | 114 +++++++++++++++ ...a => OversizedItemComponentSanitizer.java} | 91 ++++++------ .../papermc/paper/util/SafeAutoClosable.java | 10 ++ .../GlobalConfigTestingBase.java | 5 +- .../org/bukkit/support/DummyServerHelper.java | 2 +- 17 files changed, 524 insertions(+), 80 deletions(-) create mode 100644 paper-server/src/main/java/io/papermc/paper/configuration/serializer/ResourceLocationSerializer.java create mode 100644 paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java create mode 100644 paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationBinding.java create mode 100644 paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationSession.java rename paper-server/src/main/java/io/papermc/paper/util/{DataSanitizationUtil.java => OversizedItemComponentSanitizer.java} (61%) create mode 100644 paper-server/src/main/java/io/papermc/paper/util/SafeAutoClosable.java diff --git a/paper-server/patches/sources/net/minecraft/core/component/DataComponentPatch.java.patch b/paper-server/patches/sources/net/minecraft/core/component/DataComponentPatch.java.patch index 9a4fca81b..9850a5e8f 100644 --- a/paper-server/patches/sources/net/minecraft/core/component/DataComponentPatch.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/component/DataComponentPatch.java.patch @@ -1,5 +1,34 @@ --- a/net/minecraft/core/component/DataComponentPatch.java +++ b/net/minecraft/core/component/DataComponentPatch.java +@@ -86,6 +_,11 @@ + buffer.writeVarInt(0); + buffer.writeVarInt(0); + } else { ++ // Paper start - data sanitization for items ++ final io.papermc.paper.util.ItemObfuscationSession itemObfuscationSession = value.map.isEmpty() ++ ? null // Avoid thread local lookup of current session if it won't be needed anyway. ++ : io.papermc.paper.util.ItemObfuscationSession.currentSession(); ++ // Paper end - data sanitization for items + int i = 0; + int i1 = 0; + +@@ -93,7 +_,7 @@ + value.map + )) { + if (entry.getValue().isPresent()) { +- i++; ++ if (!io.papermc.paper.util.ItemComponentSanitizer.shouldDrop(itemObfuscationSession, entry.getKey())) i++; // Paper - data sanitization for items + } else { + i1++; + } +@@ -106,6 +_,7 @@ + value.map + )) { + Optional optional = entryx.getValue(); ++ optional = io.papermc.paper.util.ItemComponentSanitizer.override(itemObfuscationSession, entryx.getKey(), entryx.getValue()); // Paper - data sanitization for items + if (optional.isPresent()) { + DataComponentType dataComponentType = entryx.getKey(); + DataComponentType.STREAM_CODEC.encode(buffer, dataComponentType); @@ -125,7 +_,13 @@ } diff --git a/paper-server/patches/sources/net/minecraft/core/component/DataComponents.java.patch b/paper-server/patches/sources/net/minecraft/core/component/DataComponents.java.patch index c1f061a0a..a1a9d2377 100644 --- a/paper-server/patches/sources/net/minecraft/core/component/DataComponents.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/component/DataComponents.java.patch @@ -5,11 +5,11 @@ ); public static final DataComponentType CHARGED_PROJECTILES = register( - "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(ChargedProjectiles.STREAM_CODEC).cacheEncoding() -+ "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.CHARGED_PROJECTILES).cacheEncoding() // Paper - sanitize charged projectiles ++ "charged_projectiles", builder -> builder.persistent(ChargedProjectiles.CODEC).networkSynchronized(io.papermc.paper.util.OversizedItemComponentSanitizer.CHARGED_PROJECTILES).cacheEncoding() // Paper - sanitize charged projectiles ); public static final DataComponentType BUNDLE_CONTENTS = register( - "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(BundleContents.STREAM_CODEC).cacheEncoding() -+ "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.BUNDLE_CONTENTS).cacheEncoding() // Paper - sanitize bundle contents ++ "bundle_contents", builder -> builder.persistent(BundleContents.CODEC).networkSynchronized(io.papermc.paper.util.OversizedItemComponentSanitizer.BUNDLE_CONTENTS).cacheEncoding() // Paper - sanitize bundle contents ); public static final DataComponentType POTION_CONTENTS = register( "potion_contents", builder -> builder.persistent(PotionContents.CODEC).networkSynchronized(PotionContents.STREAM_CODEC).cacheEncoding() @@ -18,7 +18,7 @@ ); public static final DataComponentType CONTAINER = register( - "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(ItemContainerContents.STREAM_CODEC).cacheEncoding() -+ "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(io.papermc.paper.util.DataSanitizationUtil.CONTAINER).cacheEncoding() // Paper - sanitize container contents ++ "container", builder -> builder.persistent(ItemContainerContents.CODEC).networkSynchronized(io.papermc.paper.util.OversizedItemComponentSanitizer.CONTAINER).cacheEncoding() // Paper - sanitize container contents ); public static final DataComponentType BLOCK_STATE = register( "block_state", builder -> builder.persistent(BlockItemStateProperties.CODEC).networkSynchronized(BlockItemStateProperties.STREAM_CODEC).cacheEncoding() diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java.patch index cb3ea7540..d98c55251 100644 --- a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEntityDataPacket.java.patch @@ -4,7 +4,7 @@ } private static void pack(List> dataValues, RegistryFriendlyByteBuf buffer) { -+ try (io.papermc.paper.util.DataSanitizationUtil.DataSanitizer ignored = io.papermc.paper.util.DataSanitizationUtil.start(true)) { // Paper - data sanitization ++ try (io.papermc.paper.util.ItemObfuscationSession ignored = io.papermc.paper.util.ItemObfuscationSession.start(io.papermc.paper.configuration.GlobalConfiguration.get().anticheat.obfuscation.items.binding.level)) { // Paper - data sanitization for (SynchedEntityData.DataValue dataValue : dataValues) { dataValue.write(buffer); } diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java.patch index d5959b286..0021ba7c5 100644 --- a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundSetEquipmentPacket.java.patch @@ -18,7 +18,7 @@ buffer.writeVarInt(this.entity); int size = this.slots.size(); -+ try (io.papermc.paper.util.DataSanitizationUtil.DataSanitizer ignored = io.papermc.paper.util.DataSanitizationUtil.start(this.sanitize)) { // Paper - data sanitization ++ try (final io.papermc.paper.util.ItemObfuscationSession ignored = io.papermc.paper.util.ItemObfuscationSession.start(this.sanitize ? io.papermc.paper.configuration.GlobalConfiguration.get().anticheat.obfuscation.items.binding.level : io.papermc.paper.util.ItemObfuscationSession.ObfuscationLevel.NONE)) { // Paper - data sanitization for (int i = 0; i < size; i++) { Pair pair = this.slots.get(i); EquipmentSlot equipmentSlot = pair.getFirst(); diff --git a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch index 141de8193..297a82f02 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch @@ -21,14 +21,15 @@ + if (value.isEmpty() || value.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() buffer.writeVarInt(0); } else { - buffer.writeVarInt(value.getCount()); +- buffer.writeVarInt(value.getCount()); ++ buffer.writeVarInt(io.papermc.paper.util.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.ItemObfuscationSession.currentSession(), value, value.getCount())); // Paper - potentially sanitize count ITEM_STREAM_CODEC.encode(buffer, value.getItemHolder()); + // Spigot start - filter + // value = value.copy(); + // CraftItemStack.setItemMeta(value, CraftItemStack.getItemMeta(value)); // Paper - This is no longer with raw NBT being handled in metadata + // Paper start - adventure; conditionally render translatable components + boolean prev = net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.get(); -+ try { ++ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.ItemObfuscationSession.withContext(c -> c.itemStack(value))) { // pass the itemstack as context to the obfuscation session + net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true); DataComponentPatch.STREAM_CODEC.encode(buffer, value.components.asPatch()); + } finally { 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 109e569b7..4a9258b62 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 @@ -80,7 +80,7 @@ public abstract class Configurations { } @MustBeInvokedByOverriders - protected YamlConfigurationLoader.Builder createGlobalLoaderBuilder() { + protected YamlConfigurationLoader.Builder createGlobalLoaderBuilder(RegistryAccess registryAccess) { return this.createLoaderBuilder(); } @@ -104,7 +104,7 @@ public abstract class Configurations { } public G initializeGlobalConfiguration(final RegistryAccess registryAccess) throws ConfigurateException { - return this.initializeGlobalConfiguration(creator(this.globalConfigClass, true)); + return this.initializeGlobalConfiguration(registryAccess, creator(this.globalConfigClass, true)); } private void trySaveFileNode(YamlConfigurationLoader loader, ConfigurationNode node, String filename) throws ConfigurateException { @@ -117,9 +117,9 @@ public abstract class Configurations { } } - protected G initializeGlobalConfiguration(final CheckedFunction creator) throws ConfigurateException { + protected G initializeGlobalConfiguration(final RegistryAccess registryAccess, final CheckedFunction creator) throws ConfigurateException { final Path configFile = this.globalFolder.resolve(this.globalConfigFileName); - final YamlConfigurationLoader loader = this.createGlobalLoaderBuilder() + final YamlConfigurationLoader loader = this.createGlobalLoaderBuilder(registryAccess) .defaultOptions(this.applyObjectMapperFactory(this.createGlobalObjectMapperFactoryBuilder().build())) .path(configFile) .build(); 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 088b8fe5d..0b8e0ff5c 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 @@ -5,10 +5,14 @@ import io.papermc.paper.FeatureHooks; import io.papermc.paper.configuration.constraint.Constraints; import io.papermc.paper.configuration.type.number.DoubleOr; import io.papermc.paper.configuration.type.number.IntOr; +import io.papermc.paper.util.ItemObfuscationBinding; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.core.component.DataComponents; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.spongepowered.configurate.objectmapping.ConfigSerializable; @@ -20,6 +24,7 @@ import org.spongepowered.configurate.objectmapping.meta.Setting; import java.util.Map; import java.util.Objects; import java.util.OptionalInt; +import java.util.Set; @SuppressWarnings({"CanBeFinal", "FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic"}) public class GlobalConfiguration extends ConfigurationPart { @@ -69,7 +74,7 @@ public class GlobalConfiguration extends ConfigurationPart { ) public int playerMaxConcurrentChunkGenerates = 0; } - static void set(GlobalConfiguration instance) { + static void set(final GlobalConfiguration instance) { GlobalConfiguration.instance = instance; } @@ -354,4 +359,41 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean disableChorusPlantUpdates = false; public boolean disableMushroomBlockUpdates = false; } + + public Anticheat anticheat; + + public class Anticheat extends ConfigurationPart { + + public Obfuscation obfuscation; + + public class Obfuscation extends ConfigurationPart { + public Items items; + + public class Items extends ConfigurationPart { + + public boolean enableItemObfuscation = false; + public ItemObfuscationBinding.AssetObfuscationConfiguration allModels = new ItemObfuscationBinding.AssetObfuscationConfiguration( + true, + Set.of(DataComponents.LODESTONE_TRACKER), + Set.of() + ); + + public Map modelOverrides = Map.of( + Objects.requireNonNull(net.minecraft.world.item.Items.ELYTRA.components().get(DataComponents.ITEM_MODEL)), + new ItemObfuscationBinding.AssetObfuscationConfiguration( + true, + Set.of(DataComponents.DAMAGE), + Set.of() + ) + ); + + public transient ItemObfuscationBinding binding; + + @PostProcess + public void bindDataSanitizer() { + this.binding = new ItemObfuscationBinding(this); + } + } + } + } } diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/paper-server/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java index 098ab351d..e48fa405d 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java @@ -10,6 +10,7 @@ import io.papermc.paper.configuration.serializer.ComponentSerializer; import io.papermc.paper.configuration.serializer.EnumValueSerializer; import io.papermc.paper.configuration.serializer.NbtPathSerializer; import io.papermc.paper.configuration.serializer.PacketClassSerializer; +import io.papermc.paper.configuration.serializer.ResourceLocationSerializer; import io.papermc.paper.configuration.serializer.StringRepresentableSerializer; import io.papermc.paper.configuration.serializer.collections.FastutilMapSerializer; import io.papermc.paper.configuration.serializer.collections.MapSerializer; @@ -48,6 +49,7 @@ import java.util.List; import java.util.function.Function; import java.util.function.Supplier; import net.minecraft.core.RegistryAccess; +import net.minecraft.core.component.DataComponentType; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -180,6 +182,7 @@ public class PaperConfigurations extends Configurations defaultGlobalOptions(registryAccess, options)); } - private static ConfigurationOptions defaultGlobalOptions(ConfigurationOptions options) { + private static ConfigurationOptions defaultGlobalOptions(RegistryAccess registryAccess, ConfigurationOptions options) { return options .header(GLOBAL_HEADER) .serializers(builder -> builder .register(new PacketClassSerializer()) + .register(new RegistryValueSerializer<>(new TypeToken>() {}, registryAccess, Registries.DATA_COMPONENT_TYPE, false)) ); } @@ -316,7 +320,7 @@ public class PaperConfigurations extends Configurations builder.register(type -> ConfigurationPart.class.isAssignableFrom(erase(type)), factory.asTypeSerializer())); return BasicConfigurationNode.root(options); } diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java index f5ac1b029..d7c9acaff 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java @@ -88,17 +88,6 @@ public class WorldConfiguration extends ConfigurationPart { public class Anticheat extends ConfigurationPart { - public Obfuscation obfuscation; - - public class Obfuscation extends ConfigurationPart { - public Items items = new Items(); - public class Items extends ConfigurationPart { - public boolean hideItemmeta = false; - public boolean hideDurability = false; - public boolean hideItemmetaWithVisualEffects = false; - } - } - public AntiXray antiXray; public class AntiXray extends ConfigurationPart { diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/serializer/ResourceLocationSerializer.java b/paper-server/src/main/java/io/papermc/paper/configuration/serializer/ResourceLocationSerializer.java new file mode 100644 index 000000000..4bb826322 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/configuration/serializer/ResourceLocationSerializer.java @@ -0,0 +1,26 @@ +package io.papermc.paper.configuration.serializer; + +import java.lang.reflect.Type; +import java.util.function.Predicate; +import net.minecraft.resources.ResourceLocation; +import org.spongepowered.configurate.serialize.ScalarSerializer; +import org.spongepowered.configurate.serialize.SerializationException; + +public class ResourceLocationSerializer extends ScalarSerializer { + + public static final ScalarSerializer INSTANCE = new ResourceLocationSerializer(); + + private ResourceLocationSerializer() { + super(ResourceLocation.class); + } + + @Override + public ResourceLocation deserialize(final Type type, final Object obj) throws SerializationException { + return ResourceLocation.read(obj.toString()).getOrThrow(s -> new SerializationException(ResourceLocation.class, s)); + } + + @Override + protected Object serialize(final ResourceLocation item, final Predicate> typeSupported) { + return item.toString(); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java b/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java new file mode 100644 index 000000000..15236ed57 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java @@ -0,0 +1,98 @@ +package io.papermc.paper.util; + +import com.google.common.collect.ImmutableMap; +import io.papermc.paper.configuration.GlobalConfiguration; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.UnaryOperator; +import net.minecraft.Util; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.alchemy.PotionContents; +import net.minecraft.world.item.component.LodestoneTracker; +import net.minecraft.world.item.enchantment.ItemEnchantments; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public final class ItemComponentSanitizer { + + /* + * This returns for types, that when configured to be serialized, should instead return these objects. + * This is possibly because dropping the patched type may introduce visual changes. + */ + static final Map, UnaryOperator> SANITIZATION_OVERRIDES = Util.make(ImmutableMap., UnaryOperator>builder(), (map) -> { + put(map, DataComponents.LODESTONE_TRACKER, empty(new LodestoneTracker(Optional.empty(), false))); // We need it to be present to keep the glint + put(map, DataComponents.ENCHANTMENTS, empty(dummyEnchantments())); // We need to keep it present to keep the glint + put(map, DataComponents.STORED_ENCHANTMENTS, empty(dummyEnchantments())); // We need to keep it present to keep the glint + put(map, DataComponents.POTION_CONTENTS, ItemComponentSanitizer::sanitizePotionContents); // Custom situational serialization + } + ).build(); + + @SuppressWarnings({"rawtypes", "unchecked"}) + private static void put(final ImmutableMap.Builder map, final DataComponentType type, final UnaryOperator object) { + map.put(type, object); + } + + private static UnaryOperator empty(final T object) { + return (unused) -> object; + } + + private static PotionContents sanitizePotionContents(final PotionContents potionContents) { + // We have a custom color! We can hide everything! + if (potionContents.customColor().isPresent()) { + return new PotionContents(Optional.empty(), potionContents.customColor(), List.of(), Optional.empty()); + } + + // WE cannot hide anything really, as the color is a mix of potion/potion contents, which can + // possibly be reversed. + return potionContents; + } + + // We cant use the empty map from enchantments because we want to keep the glow + private static ItemEnchantments dummyEnchantments() { + final ItemEnchantments.Mutable obj = new ItemEnchantments.Mutable(ItemEnchantments.EMPTY); + obj.set(MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getRandom(RandomSource.create()).orElseThrow(), 1); + return obj.toImmutable(); + } + + public static int sanitizeCount(final ItemObfuscationSession obfuscationSession, final ItemStack itemStack, final int count) { + if (obfuscationSession.obfuscationLevel() != ItemObfuscationSession.ObfuscationLevel.ALL) return count; // Ignore if we are not obfuscating + + if (GlobalConfiguration.get().anticheat.obfuscation.items.binding.getAssetObfuscation(itemStack).sanitizeCount()) { + return 1; + } else { + return count; + } + } + + public static boolean shouldDrop(final ItemObfuscationSession obfuscationSession, final DataComponentType key) { + if (obfuscationSession.obfuscationLevel() != ItemObfuscationSession.ObfuscationLevel.ALL) return false; // Ignore if we are not obfuscating + + final ItemStack targetItemstack = obfuscationSession.context().itemStack(); + + // Only drop if configured to do so. + return GlobalConfiguration.get().anticheat.obfuscation.items.binding.getAssetObfuscation(targetItemstack).patchStrategy().get(key) == ItemObfuscationBinding.BoundObfuscationConfiguration.MutationType.Drop.INSTANCE; + } + + public static Optional override(final ItemObfuscationSession obfuscationSession, final DataComponentType key, final Optional value) { + if (obfuscationSession.obfuscationLevel() != ItemObfuscationSession.ObfuscationLevel.ALL) return value; // Ignore if we are not obfuscating + + // Ignore removed values + if (value.isEmpty()) { + return value; + } + + final ItemStack targetItemstack = obfuscationSession.context().itemStack(); + + return switch (GlobalConfiguration.get().anticheat.obfuscation.items.binding.getAssetObfuscation(targetItemstack).patchStrategy().get(key)) { + case final ItemObfuscationBinding.BoundObfuscationConfiguration.MutationType.Drop ignored -> Optional.empty(); + case final ItemObfuscationBinding.BoundObfuscationConfiguration.MutationType.Sanitize sanitize -> Optional.of(sanitize.sanitizer().apply(value.get())); + case null -> value; + }; + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationBinding.java b/paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationBinding.java new file mode 100644 index 000000000..db7ac8a93 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationBinding.java @@ -0,0 +1,133 @@ +package io.papermc.paper.util; + +import io.papermc.paper.configuration.GlobalConfiguration; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.UnaryOperator; +import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import org.jspecify.annotations.NullMarked; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; +import org.spongepowered.configurate.objectmapping.meta.Required; + +/** + * The item obfuscation binding is a state bound by the configured item obfuscation. + * It only hosts the bound and computed data from the global configuration. + */ +@NullMarked +public final class ItemObfuscationBinding { + + public final ItemObfuscationSession.ObfuscationLevel level; + private final BoundObfuscationConfiguration base; + private final Map overrides; + + public ItemObfuscationBinding(final GlobalConfiguration.Anticheat.Obfuscation.Items items) { + this.level = items.enableItemObfuscation ? ItemObfuscationSession.ObfuscationLevel.ALL : ItemObfuscationSession.ObfuscationLevel.OVERSIZED; + this.base = bind(items.allModels); + final Map overrides = new HashMap<>(); + for (final Map.Entry entry : items.modelOverrides.entrySet()) { + overrides.put(entry.getKey(), bind(entry.getValue())); + } + this.overrides = Collections.unmodifiableMap(overrides); + } + + public record BoundObfuscationConfiguration(boolean sanitizeCount, + Map, MutationType> patchStrategy) { + + sealed interface MutationType permits MutationType.Drop, MutationType.Sanitize { + enum Drop implements MutationType { + INSTANCE + } + + record Sanitize(UnaryOperator sanitizer) implements MutationType { + + } + } + } + + @ConfigSerializable + public record AssetObfuscationConfiguration(@Required boolean sanitizeCount, + Set> dontObfuscate, + Set> alsoObfuscate) { + + } + + private static BoundObfuscationConfiguration bind(final AssetObfuscationConfiguration config) { + final Set> base = new HashSet<>(BASE_OVERRIDERS); + base.addAll(config.alsoObfuscate()); + base.removeAll(config.dontObfuscate()); + + final Map, BoundObfuscationConfiguration.MutationType> finalStrategy = new HashMap<>(); + // Configure what path the data component should go through, should it be dropped, or should it be sanitized? + for (final DataComponentType type : base) { + // We require some special logic, sanitize it rather than dropping it. + final UnaryOperator sanitizationOverride = ItemComponentSanitizer.SANITIZATION_OVERRIDES.get(type); + if (sanitizationOverride != null) { + finalStrategy.put(type, new BoundObfuscationConfiguration.MutationType.Sanitize(sanitizationOverride)); + } else { + finalStrategy.put(type, BoundObfuscationConfiguration.MutationType.Drop.INSTANCE); + } + } + + return new BoundObfuscationConfiguration(config.sanitizeCount(), finalStrategy); + } + + public BoundObfuscationConfiguration getAssetObfuscation(final ItemStack itemStack) { + if (this.overrides.isEmpty()) { + return this.base; + } + return this.overrides.getOrDefault(itemStack.get(DataComponents.ITEM_MODEL), this.base); + } + + static final Set> BASE_OVERRIDERS = Set.of( + DataComponents.MAX_STACK_SIZE, + DataComponents.MAX_DAMAGE, + DataComponents.DAMAGE, + DataComponents.UNBREAKABLE, + DataComponents.CUSTOM_NAME, + DataComponents.ITEM_NAME, + DataComponents.LORE, + DataComponents.RARITY, + DataComponents.ENCHANTMENTS, + DataComponents.CAN_PLACE_ON, + DataComponents.CAN_BREAK, + DataComponents.ATTRIBUTE_MODIFIERS, + DataComponents.HIDE_ADDITIONAL_TOOLTIP, + DataComponents.HIDE_TOOLTIP, + DataComponents.REPAIR_COST, + DataComponents.USE_REMAINDER, + DataComponents.FOOD, + DataComponents.DAMAGE_RESISTANT, + // Not important on the player + DataComponents.TOOL, + DataComponents.ENCHANTABLE, + DataComponents.REPAIRABLE, + DataComponents.GLIDER, + DataComponents.TOOLTIP_STYLE, + DataComponents.DEATH_PROTECTION, + DataComponents.STORED_ENCHANTMENTS, + DataComponents.MAP_ID, + DataComponents.POTION_CONTENTS, + DataComponents.SUSPICIOUS_STEW_EFFECTS, + DataComponents.WRITABLE_BOOK_CONTENT, + DataComponents.WRITTEN_BOOK_CONTENT, + DataComponents.CUSTOM_DATA, + DataComponents.ENTITY_DATA, + DataComponents.BUCKET_ENTITY_DATA, + DataComponents.BLOCK_ENTITY_DATA, + DataComponents.INSTRUMENT, + DataComponents.OMINOUS_BOTTLE_AMPLIFIER, + DataComponents.JUKEBOX_PLAYABLE, + DataComponents.LODESTONE_TRACKER, + DataComponents.FIREWORKS, + DataComponents.NOTE_BLOCK_SOUND, + DataComponents.BEES, + DataComponents.LOCK, + DataComponents.CONTAINER_LOOT + ); +} diff --git a/paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationSession.java b/paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationSession.java new file mode 100644 index 000000000..deafa923d --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/util/ItemObfuscationSession.java @@ -0,0 +1,114 @@ +package io.papermc.paper.util; + +import java.util.function.UnaryOperator; +import com.google.common.base.Preconditions; +import net.minecraft.world.item.ItemStack; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * The item obfuscation session may be started by a thread to indicate that items should be obfuscated when serialized + * for network usage. + *

+ * A session is persistent throughout an entire thread and will be "activated" by passing an {@link ObfuscationContext} + * to start/switch context methods. + */ +@NullMarked +public class ItemObfuscationSession implements SafeAutoClosable { + + static final ThreadLocal THREAD_LOCAL_SESSION = ThreadLocal.withInitial(ItemObfuscationSession::new); + + public static ItemObfuscationSession currentSession() { + return THREAD_LOCAL_SESSION.get(); + } + + /** + * Obfuscation level on a specific context. + */ + public enum ObfuscationLevel { + NONE, + OVERSIZED, + ALL; + + public boolean obfuscateOversized() { + return switch (this) { + case OVERSIZED, ALL -> true; + default -> false; + }; + } + + public boolean isObfuscating() { + return this != NONE; + } + } + + public static ItemObfuscationSession start(final ObfuscationLevel level) { + final ItemObfuscationSession sanitizer = THREAD_LOCAL_SESSION.get(); + sanitizer.switchContext(new ObfuscationContext(sanitizer, null, null, level)); + return sanitizer; + } + + /** + * Updates the context of the currently running session by requiring the unary operator to emit a new context + * based on the current one. + * The method expects the caller to use the withers on the context. + * + * @param contextUpdater the operator to construct the new context. + * @return the context callback to close once the context expires. + */ + public static SafeAutoClosable withContext(final UnaryOperator contextUpdater) { + final ItemObfuscationSession session = THREAD_LOCAL_SESSION.get(); + + // Don't pass any context if we are not currently sanitizing + if (!session.obfuscationLevel().isObfuscating()) return () -> { + }; + + final ObfuscationContext newContext = contextUpdater.apply(session.context()); + Preconditions.checkState(newContext != session.context(), "withContext yielded same context instance, this will break the stack on close"); + session.switchContext(newContext); + return newContext; + } + + private final ObfuscationContext root = new ObfuscationContext(this, null, null, ObfuscationLevel.NONE); + private ObfuscationContext context = root; + + public void switchContext(final ObfuscationContext context) { + this.context = context; + } + + public ObfuscationContext context() { + return this.context; + } + + @Override + public void close() { + this.context = root; + } + + public ObfuscationLevel obfuscationLevel() { + return this.context.level; + } + + public record ObfuscationContext( + ItemObfuscationSession parent, + @Nullable ObfuscationContext previousContext, + @Nullable ItemStack itemStack, + ObfuscationLevel level + ) implements SafeAutoClosable { + + public ObfuscationContext itemStack(final ItemStack itemStack) { + return new ObfuscationContext(this.parent, this, itemStack, this.level); + } + + public ObfuscationContext level(final ObfuscationLevel obfuscationLevel) { + return new ObfuscationContext(this.parent, this, this.itemStack, obfuscationLevel); + } + + @Override + public void close() { + // Restore the previous context when this context is closed. + this.parent().switchContext(this.previousContext); + } + } + +} diff --git a/paper-server/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java b/paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java similarity index 61% rename from paper-server/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java rename to paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java index 72483dedd..56f3a9324 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/DataSanitizationUtil.java +++ b/paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java @@ -1,9 +1,8 @@ package io.papermc.paper.util; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.UnaryOperator; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import java.util.List; +import java.util.function.UnaryOperator; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.util.Mth; @@ -12,26 +11,38 @@ import net.minecraft.world.item.Items; import net.minecraft.world.item.component.BundleContents; import net.minecraft.world.item.component.ChargedProjectiles; import net.minecraft.world.item.component.ItemContainerContents; -import org.apache.commons.lang3.math.Fraction; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; -@DefaultQualifier(NonNull.class) -public final class DataSanitizationUtil { +public final class OversizedItemComponentSanitizer { - private static final ThreadLocal DATA_SANITIZER = ThreadLocal.withInitial(DataSanitizer::new); - - public static DataSanitizer start(final boolean sanitize) { - final DataSanitizer sanitizer = DATA_SANITIZER.get(); - if (sanitize) { - sanitizer.start(); - } - return sanitizer; - } - - public static final StreamCodec CHARGED_PROJECTILES = codec(ChargedProjectiles.STREAM_CODEC, DataSanitizationUtil::sanitizeChargedProjectiles); - public static final StreamCodec BUNDLE_CONTENTS = codec(BundleContents.STREAM_CODEC, DataSanitizationUtil::sanitizeBundleContents); + /* + These represent codecs that are meant to help get rid of possibly big items by ALWAYS hiding this data. + */ + public static final StreamCodec CHARGED_PROJECTILES = codec(ChargedProjectiles.STREAM_CODEC, OversizedItemComponentSanitizer::sanitizeChargedProjectiles); public static final StreamCodec CONTAINER = codec(ItemContainerContents.STREAM_CODEC, contents -> ItemContainerContents.EMPTY); + public static final StreamCodec BUNDLE_CONTENTS = new StreamCodec<>() { + @Override + public BundleContents decode(final RegistryFriendlyByteBuf buffer) { + return BundleContents.STREAM_CODEC.decode(buffer); + } + + @Override + public void encode(final RegistryFriendlyByteBuf buffer, final BundleContents value) { + if (!ItemObfuscationSession.currentSession().obfuscationLevel().obfuscateOversized()) { + BundleContents.STREAM_CODEC.encode(buffer, value); + return; + } + + // Disable further obfuscation to skip e.g. count. + try (final SafeAutoClosable ignored = ItemObfuscationSession.withContext(c -> c.level(ItemObfuscationSession.ObfuscationLevel.OVERSIZED))){ + BundleContents.STREAM_CODEC.encode(buffer, sanitizeBundleContents(value)); + } + } + }; + + private static StreamCodec codec(final StreamCodec delegate, final UnaryOperator sanitizer) { + return new DataSanitizationCodec<>(delegate, sanitizer); + } private static ChargedProjectiles sanitizeChargedProjectiles(final ChargedProjectiles projectiles) { if (projectiles.isEmpty()) { @@ -39,21 +50,26 @@ public final class DataSanitizationUtil { } return ChargedProjectiles.of(List.of( - new ItemStack(projectiles.contains(Items.FIREWORK_ROCKET) ? Items.FIREWORK_ROCKET : Items.ARROW) - )); + new ItemStack( + projectiles.contains(Items.FIREWORK_ROCKET) + ? Items.FIREWORK_ROCKET + : Items.ARROW + ))); } + // Although bundles no longer change their size based on fullness, fullness is exposed in item models. private static BundleContents sanitizeBundleContents(final BundleContents contents) { if (contents.isEmpty()) { return contents; } - // Bundles change their texture based on their fullness. // A bundles content weight may be anywhere from 0 to, basically, infinity. // A weight of 1 is the usual maximum case int sizeUsed = Mth.mulAndTruncate(contents.weight(), 64); // Early out, *most* bundles should not be overfilled above a weight of one. - if (sizeUsed <= 64) return new BundleContents(List.of(new ItemStack(Items.PAPER, Math.max(1, sizeUsed)))); + if (sizeUsed <= 64) { + return new BundleContents(List.of(new ItemStack(Items.PAPER, Math.max(1, sizeUsed)))); + } final List sanitizedRepresentation = new ObjectArrayList<>(sizeUsed / 64 + 1); while (sizeUsed > 0) { @@ -66,20 +82,19 @@ public final class DataSanitizationUtil { return new BundleContents(sanitizedRepresentation); } - private static StreamCodec codec(final StreamCodec delegate, final UnaryOperator sanitizer) { - return new DataSanitizationCodec<>(delegate, sanitizer); - } - - private record DataSanitizationCodec(StreamCodec delegate, UnaryOperator sanitizer) implements StreamCodec { + // Codec used to override encoding if sanitization is enabled + private record DataSanitizationCodec(StreamCodec delegate, + UnaryOperator sanitizer) implements StreamCodec { @Override public @NonNull A decode(final @NonNull B buf) { return this.delegate.decode(buf); } + @SuppressWarnings("resource") @Override public void encode(final @NonNull B buf, final @NonNull A value) { - if (!DATA_SANITIZER.get().value().get()) { + if (ItemObfuscationSession.currentSession().obfuscationLevel().obfuscateOversized()) { this.delegate.encode(buf, value); } else { this.delegate.encode(buf, this.sanitizer.apply(value)); @@ -87,22 +102,4 @@ public final class DataSanitizationUtil { } } - public record DataSanitizer(AtomicBoolean value) implements AutoCloseable { - - public DataSanitizer() { - this(new AtomicBoolean(false)); - } - - public void start() { - this.value.compareAndSet(false, true); - } - - @Override - public void close() { - this.value.compareAndSet(true, false); - } - } - - private DataSanitizationUtil() { - } } diff --git a/paper-server/src/main/java/io/papermc/paper/util/SafeAutoClosable.java b/paper-server/src/main/java/io/papermc/paper/util/SafeAutoClosable.java new file mode 100644 index 000000000..4bc1c5853 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/util/SafeAutoClosable.java @@ -0,0 +1,10 @@ +package io.papermc.paper.util; + +/** + * A type of {@link AutoCloseable} that does not throw a checked exception. + */ +public interface SafeAutoClosable extends AutoCloseable { + + @Override + void close(); +} diff --git a/paper-server/src/test/java/io/papermc/paper/configuration/GlobalConfigTestingBase.java b/paper-server/src/test/java/io/papermc/paper/configuration/GlobalConfigTestingBase.java index 039658979..355dcdb7c 100644 --- a/paper-server/src/test/java/io/papermc/paper/configuration/GlobalConfigTestingBase.java +++ b/paper-server/src/test/java/io/papermc/paper/configuration/GlobalConfigTestingBase.java @@ -1,14 +1,15 @@ package io.papermc.paper.configuration; +import net.minecraft.core.RegistryAccess; import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.serialize.SerializationException; public final class GlobalConfigTestingBase { - public static void setupGlobalConfigForTest() { + public static void setupGlobalConfigForTest(RegistryAccess registryAccess) { //noinspection ConstantConditions if (GlobalConfiguration.get() == null) { - ConfigurationNode node = PaperConfigurations.createForTesting(); + ConfigurationNode node = PaperConfigurations.createForTesting(registryAccess); try { GlobalConfiguration globalConfiguration = node.require(GlobalConfiguration.class); GlobalConfiguration.set(globalConfiguration); diff --git a/paper-server/src/test/java/org/bukkit/support/DummyServerHelper.java b/paper-server/src/test/java/org/bukkit/support/DummyServerHelper.java index 309d37124..78c0d08f6 100644 --- a/paper-server/src/test/java/org/bukkit/support/DummyServerHelper.java +++ b/paper-server/src/test/java/org/bukkit/support/DummyServerHelper.java @@ -91,7 +91,7 @@ public final class DummyServerHelper { when(instance.getPluginManager()).thenReturn(pluginManager); // Paper end - testing additions - io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(); // Paper - configuration files - setup global configuration test base + io.papermc.paper.configuration.GlobalConfigTestingBase.setupGlobalConfigForTest(RegistryHelper.getRegistry()); // Paper - configuration files - setup global configuration test base // Paper start - add test for recipe conversion when(instance.recipeIterator()).thenAnswer(ignored -> From 08fc33ca031ec8111bf91c802af386ce0ec50df1 Mon Sep 17 00:00:00 2001 From: spring-dependency-management <193335777+spring-dependency-management@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:02:03 +0000 Subject: [PATCH 017/203] Update CustomTimingsHandler Nag Message (#11923) --- paper-api/src/main/java/org/spigotmc/CustomTimingsHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/spigotmc/CustomTimingsHandler.java b/paper-api/src/main/java/org/spigotmc/CustomTimingsHandler.java index 12946bd55..5fbacfcf1 100644 --- a/paper-api/src/main/java/org/spigotmc/CustomTimingsHandler.java +++ b/paper-api/src/main/java/org/spigotmc/CustomTimingsHandler.java @@ -48,7 +48,7 @@ public final class CustomTimingsHandler { public CustomTimingsHandler(@NotNull String name) { Timing timing; - new AuthorNagException("Deprecated use of CustomTimingsHandler. Please Switch to Timings.of ASAP").printStackTrace(); + new AuthorNagException("Deprecated use of CustomTimingsHandler. Timings has been removed.").printStackTrace(); try { final Method ofSafe = TimingsManager.class.getDeclaredMethod("getHandler", String.class, String.class, Timing.class); ofSafe.setAccessible(true); From 5e14504f2007839741db4dadb32f8fdb4a9f5443 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Thu, 9 Jan 2025 17:08:28 -0300 Subject: [PATCH 018/203] [ci skip] Add missing deprecated docs for isEnabledByFeature (#11938) --- paper-api/src/main/java/org/bukkit/Material.java | 3 ++- paper-api/src/main/java/org/bukkit/block/BlockType.java | 4 ++-- paper-api/src/main/java/org/bukkit/entity/EntityType.java | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Material.java b/paper-api/src/main/java/org/bukkit/Material.java index e89edabd3..9afafc00e 100644 --- a/paper-api/src/main/java/org/bukkit/Material.java +++ b/paper-api/src/main/java/org/bukkit/Material.java @@ -5706,8 +5706,9 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla * * @param world the world to check * @return true if this material can be used in this World. + * @deprecated use {@link io.papermc.paper.world.flag.FeatureFlagSetHolder#isEnabled(io.papermc.paper.world.flag.FeatureDependant)} */ - @Deprecated(forRemoval = true, since = "1.20") // Paper + @Deprecated(forRemoval = true, since = "1.20") public boolean isEnabledByFeature(@NotNull World world) { if (isItem()) { return Bukkit.getDataPackManager().isEnabledByFeature(asItemType(), world); diff --git a/paper-api/src/main/java/org/bukkit/block/BlockType.java b/paper-api/src/main/java/org/bukkit/block/BlockType.java index a340e78a4..6e24b05c9 100644 --- a/paper-api/src/main/java/org/bukkit/block/BlockType.java +++ b/paper-api/src/main/java/org/bukkit/block/BlockType.java @@ -3551,7 +3551,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * state as well. This method will return true if there is at least one * state in which additional interact handling is performed for the * block type. - * + * * @deprecated This method is not comprehensive and does not accurately reflect what block types are * interactable. Many "interactions" are defined on the item not block, and many are conditional on some other world state * checks being true. @@ -3604,7 +3604,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran * * @param world the world to check * @return true if this BlockType can be used in this World. - * @deprecated Use {@link io.papermc.paper.world.flag.FeatureFlagSetHolder#isEnabled(io.papermc.paper.world.flag.FeatureDependant)} + * @deprecated use {@link io.papermc.paper.world.flag.FeatureFlagSetHolder#isEnabled(io.papermc.paper.world.flag.FeatureDependant)} */ @Deprecated(forRemoval = true, since = "1.21.1") // Paper boolean isEnabledByFeature(@NotNull World world); diff --git a/paper-api/src/main/java/org/bukkit/entity/EntityType.java b/paper-api/src/main/java/org/bukkit/entity/EntityType.java index 0251ec12e..29d225116 100644 --- a/paper-api/src/main/java/org/bukkit/entity/EntityType.java +++ b/paper-api/src/main/java/org/bukkit/entity/EntityType.java @@ -503,8 +503,9 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans * * @param world the world to check * @return true if this EntityType can be used to spawn an Entity for this World. + * @deprecated use {@link io.papermc.paper.world.flag.FeatureFlagSetHolder#isEnabled(io.papermc.paper.world.flag.FeatureDependant)} */ - @Deprecated(forRemoval = true, since = "1.20") // Paper + @Deprecated(forRemoval = true, since = "1.20") public boolean isEnabledByFeature(@NotNull World world) { return Bukkit.getDataPackManager().isEnabledByFeature(this, world); } From 400717174e9ec4ea45838cda09c2cf2f020aa931 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 10 Jan 2025 14:38:50 +0100 Subject: [PATCH 019/203] Correct obfuscation of oversized items (#11944) --- .../io/papermc/paper/util/OversizedItemComponentSanitizer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java b/paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java index 56f3a9324..fc20f3f61 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java +++ b/paper-server/src/main/java/io/papermc/paper/util/OversizedItemComponentSanitizer.java @@ -94,7 +94,7 @@ public final class OversizedItemComponentSanitizer { @SuppressWarnings("resource") @Override public void encode(final @NonNull B buf, final @NonNull A value) { - if (ItemObfuscationSession.currentSession().obfuscationLevel().obfuscateOversized()) { + if (!ItemObfuscationSession.currentSession().obfuscationLevel().obfuscateOversized()) { this.delegate.encode(buf, value); } else { this.delegate.encode(buf, this.sanitizer.apply(value)); From 1b38f2810ee33c8814a4d0183d389e55e3cfaeef Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 10 Jan 2025 19:49:58 +0100 Subject: [PATCH 020/203] Fix reading recipes used on furnace (#11947) --- .../level/block/entity/AbstractFurnaceBlockEntity.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch index 5907877ed..f8c59e895 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -55,7 +55,7 @@ + // Paper start - Validate ResourceLocation + final ResourceLocation resourceLocation = ResourceLocation.tryParse(string); + if (resourceLocation != null) { -+ this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, resourceLocation), tag.getInt(string)); ++ this.recipesUsed.put(ResourceKey.create(Registries.RECIPE, resourceLocation), compound.getInt(string)); + } + // Paper end - Validate ResourceLocation + } From b03d39b5ce6b5046ce6854ddba74e8ae3641c230 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:01:17 -0700 Subject: [PATCH 021/203] [ci skip] Update paperweight to 2.0.0-beta.13 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index b4efe371f..9a7683700 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ import java.nio.file.Path import kotlin.random.Random plugins { - id("io.papermc.paperweight.core") version "2.0.0-beta.10" apply false + id("io.papermc.paperweight.core") version "2.0.0-beta.13" apply false } subprojects { From 6316a50dbd7ccfa2724c95938104b85e99bae17f Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 11 Jan 2025 00:13:45 -0800 Subject: [PATCH 022/203] Make CraftServer#isPrimaryThread use TickThread check This diff was accidentally dropped when updating to hard fork. This diff importantly: - Does not return true if the async catcher is disabled - Does not return true during shutdown - Returns true for any instance of TickThread (enables watchdog and Folia threads to be considered main) --- .../src/main/java/org/bukkit/craftbukkit/CraftServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 381448d8e..fda9daa63 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2550,7 +2550,7 @@ public final class CraftServer implements Server { @Override public boolean isPrimaryThread() { - return Thread.currentThread().equals(this.console.serverThread) || this.console.hasStopped() || !org.spigotmc.AsyncCatcher.enabled; // All bets are off if we have shut down (e.g. due to watchdog) + return ca.spottedleaf.moonrise.common.util.TickThread.isTickThread(); // Paper - rewrite chunk system } // Paper start - Adventure From ea7b9619261495fc94970b2b0745cf1ec15d16ab Mon Sep 17 00:00:00 2001 From: Owen <23108066+Owen1212055@users.noreply.github.com> Date: Sat, 11 Jan 2025 04:49:31 -0500 Subject: [PATCH 023/203] Fix MapItem incorectly fetching water biomes on treasure maps (#11936) --- .../patches/sources/net/minecraft/world/item/MapItem.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch index c31ec01d7..8488078d8 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch @@ -16,7 +16,7 @@ for (int i5 = 0; i5 < 128; i5++) { for (int i6 = 0; i6 < 128; i6++) { - Holder biome = serverLevel.getBiome(mutableBlockPos.set((i3 + i6) * i, 0, (i4 + i5) * i)); -+ Holder biome = serverLevel.getUncachedNoiseBiome((i3 + i6) * i, 0, (i4 + i5) * i); // Paper - Perf: Use seed based lookup for treasure maps ++ Holder biome = serverLevel.getUncachedNoiseBiome(net.minecraft.core.QuartPos.fromBlock((i3 + i6) * i), net.minecraft.core.QuartPos.fromBlock(0), net.minecraft.core.QuartPos.fromBlock((i4 + i5) * i)); // Paper - Perf: Use seed based lookup for treasure maps flags[i5 * 128 + i6] = biome.is(BiomeTags.WATER_ON_MAP_OUTLINES); } } From b242f1eb15cdde90a6a9216495a031eaeed6fced Mon Sep 17 00:00:00 2001 From: SoSeDiK Date: Sat, 11 Jan 2025 11:59:50 +0200 Subject: [PATCH 024/203] Prevent day cycle on the client when using fixed time (#11924) --- .../features/0017-Moonrise-optimisation-patches.patch | 8 ++++---- paper-server/patches/features/0029-Optimize-Hoppers.patch | 6 +++--- .../net/minecraft/server/MinecraftServer.java.patch | 7 ++++--- .../src/main/java/org/bukkit/craftbukkit/CraftWorld.java | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch index 13e59780d..6d5960f46 100644 --- a/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0017-Moonrise-optimisation-patches.patch @@ -23552,7 +23552,7 @@ index 2b46ca9a2a046063cad422bec00d76107537b091..9aa664537cc37e44db46d5a2a64ae311 thread1 -> { DedicatedServer dedicatedServer1 = new DedicatedServer( diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index b92a3da5c325e69f5601416d4205fb33429742b3..d967d605c2e4227ae980c30f1c8b86edbc680d6d 100644 +index 841a41485af62470d833aba578069b19a0bd1e8d..409c1134327bfcc338c3ac5e658a83cc396645d1 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -173,7 +173,7 @@ import net.minecraft.world.phys.Vec2; @@ -23737,7 +23737,7 @@ index b92a3da5c325e69f5601416d4205fb33429742b3..d967d605c2e4227ae980c30f1c8b86ed return true; } else { boolean ret = false; // Paper - force execution of all worlds, do not just bias the first -@@ -2472,6 +2554,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent serverLevel.updateLagCompensationTick(); // Paper - lag compensation @@ -60,7 +60,7 @@ index 6dbae12bbfd47cd4e75bc3089561e8e226e9e604..9c859025302ddb2c20cf6457fa4e4eaf /* Drop global time updates if (this.tickCount % 20 == 0) { diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index c255e11cb0981bd7e0456d4fd401beb5257be597..d6361863d6a1e364de262d6199373cbd68d1c699 100644 +index 47bf8051da9a04ab333bb2bf6421d6253556b71c..ba31bbdac96e58d299dc260b47aaedf767735a42 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java @@ -808,10 +808,16 @@ public final class ItemStack implements DataComponentHolder { diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch index 6009edbd8..868865c03 100644 --- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -984,7 +984,7 @@ ObjectArrayList list = new ObjectArrayList<>(min); int randomInt = Mth.nextInt(this.random, 0, players.size() - min); -@@ -1046,17 +_,65 @@ +@@ -1046,17 +_,66 @@ protected void tickChildren(BooleanSupplier hasTimeLeft) { ProfilerFiller profilerFiller = Profiler.get(); this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing()); @@ -1027,8 +1027,9 @@ + } + ServerPlayer entityplayer = (ServerPlayer) entityhuman; + long playerTime = entityplayer.getPlayerTime(); -+ ClientboundSetTimePacket packet = (playerTime == dayTime) ? worldPacket : -+ new ClientboundSetTimePacket(worldTime, playerTime, doDaylight); ++ boolean relativeTime = entityplayer.relativeTime; ++ ClientboundSetTimePacket packet = ((relativeTime || !doDaylight) && playerTime == dayTime) ? worldPacket : ++ new ClientboundSetTimePacket(worldTime, playerTime, relativeTime && doDaylight); + entityplayer.connection.send(packet); // Add support for per player time + // Paper end - Perf: Optimize time updates + } 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 544305f9d..281969314 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -854,7 +854,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { CraftPlayer cp = (CraftPlayer) p; if (cp.getHandle().connection == null) continue; - cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().serverLevel().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); + cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().serverLevel().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); } } From 3e42518b34ff38f60aaa08577c035cd8158dcac9 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Sat, 11 Jan 2025 02:10:32 -0800 Subject: [PATCH 025/203] Fix snow accumulating in custom biomes without precipitation (#11854) --- .../net/minecraft/world/level/biome/Biome.java.patch | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/biome/Biome.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/level/biome/Biome.java.patch b/paper-server/patches/sources/net/minecraft/world/level/biome/Biome.java.patch new file mode 100644 index 000000000..df0ac9026 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/biome/Biome.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/biome/Biome.java ++++ b/net/minecraft/world/level/biome/Biome.java +@@ -176,7 +_,7 @@ + } + + public boolean shouldSnow(LevelReader level, BlockPos pos) { +- if (this.warmEnoughToRain(pos, level.getSeaLevel())) { ++ if (this.getPrecipitationAt(pos, level.getSeaLevel()) != Precipitation.SNOW) { // Paper - Fixes MC-248212 + return false; + } else { + if (level.isInsideBuildHeight(pos.getY()) && level.getBrightness(LightLayer.BLOCK, pos) < 10) { From 3d9ecc4e085d9cfb6c97fd7efe877b3468c6b4fb Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 11 Jan 2025 04:52:21 -0800 Subject: [PATCH 026/203] Log thread check parameters when the thread check fails This provides additional debug information that may be useful. --- .../moonrise/common/util/TickThread.java | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java index 217d1f908..157e5edb5 100644 --- a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +++ b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java @@ -28,43 +28,64 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) { if (!isTickThreadFor(world, pos)) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); - throw new IllegalStateException(reason); + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos; + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); + } + } + + public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) { + if (!isTickThreadFor(world, pos, blockRadius)) { + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius; + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); } } public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) { if (!isTickThreadFor(world, pos)) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); - throw new IllegalStateException(reason); + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos; + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); } } public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) { if (!isTickThreadFor(world, chunkX, chunkZ)) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); - throw new IllegalStateException(reason); + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ); + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); } } public static void ensureTickThread(final Entity entity, final String reason) { if (!isTickThreadFor(entity)) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); - throw new IllegalStateException(reason); + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", entity=" + entity; + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); } } public static void ensureTickThread(final Level world, final AABB aabb, final String reason) { if (!isTickThreadFor(world, aabb)) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); - throw new IllegalStateException(reason); + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb; + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); } } public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) { if (!isTickThreadFor(world, blockX, blockZ)) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); - throw new IllegalStateException(reason); + final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + + reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ); + LOGGER.error(ex, new Throwable()); + throw new IllegalStateException(ex); } } @@ -105,6 +126,10 @@ public class TickThread extends Thread { return isTickThread(); } + public static boolean isTickThreadFor(final Level world, final BlockPos pos, final int blockRadius) { + return isTickThread(); + } + public static boolean isTickThreadFor(final Level world, final ChunkPos pos) { return isTickThread(); } From 3ad3fbc19ad6a85a7a992f907e3e5f98cad85b68 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 11 Jan 2025 06:28:56 -0800 Subject: [PATCH 027/203] Update to Concurrentutil 0.0.3 --- paper-server/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index 21385e4dd..9367f2a15 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -124,7 +124,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { dependencies { implementation(project(":paper-api")) - implementation("ca.spottedleaf:concurrentutil:0.0.2") + implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 implementation("net.minecrell:terminalconsoleappender:1.3.0") From 79ffcd153671d99ec415e9d1254267f524f6fd11 Mon Sep 17 00:00:00 2001 From: Miles <81843550+Y2Kwastaken@users.noreply.github.com> Date: Sat, 11 Jan 2025 17:44:20 +0000 Subject: [PATCH 028/203] Fix vanilla parity on enchantable items with no targets (#11896) --- .../minecraft/world/inventory/EnchantmentMenu.java.patch | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch index e37648a0f..dbdb35bbc 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/EnchantmentMenu.java.patch @@ -97,7 +97,7 @@ + .bukkitToMinecraftHolder(offer.getEnchantment())); + this.levelClue[j] = offer.getEnchantmentLevel(); + } else { -+ this.costs[j] = 0; ++ if (enchantClue[j] != -1) this.costs[j] = 0; + this.enchantClue[j] = -1; + this.levelClue[j] = -1; + } @@ -107,7 +107,7 @@ this.broadcastChanges(); }); } else { -@@ -145,19 +_,51 @@ +@@ -145,19 +_,53 @@ return false; } else { this.access.execute((level, blockPos) -> { @@ -124,7 +124,9 @@ + enchants.put(org.bukkit.craftbukkit.enchantments.CraftEnchantment.minecraftHolderToBukkit(instance.enchantment), instance.level); + } + org.bukkit.craftbukkit.inventory.CraftItemStack craftItemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack); -+ org.bukkit.enchantments.Enchantment hintedEnchantment = org.bukkit.craftbukkit.enchantments.CraftEnchantment.minecraftHolderToBukkit(registry.byId(this.enchantClue[id])); ++ Holder holder = registry.byId(this.enchantClue[id]); ++ if (holder == null) return; ++ org.bukkit.enchantments.Enchantment hintedEnchantment = org.bukkit.craftbukkit.enchantments.CraftEnchantment.minecraftHolderToBukkit(holder); + int hintedEnchantmentLevel = this.levelClue[id]; + org.bukkit.event.enchantment.EnchantItemEvent event = new org.bukkit.event.enchantment.EnchantItemEvent((org.bukkit.entity.Player) player.getBukkitEntity(), this.getBukkitView(), this.access.getLocation().getBlock(), craftItemStack, this.costs[id], enchants, hintedEnchantment, hintedEnchantmentLevel, id); + level.getCraftServer().getPluginManager().callEvent(event); From 19ddbeff9e1de5821b4f2b18987c5103f30d7989 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:50:24 +0100 Subject: [PATCH 029/203] Fix InventoryAction wrong for Bundles (#11902) --- build-data/paper.at | 1 + .../event/inventory/InventoryAction.java | 24 +++++++++++++ .../ServerGamePacketListenerImpl.java.patch | 36 ++++++++++++++++--- .../item/component/BundleContents.java.patch | 30 ++++++++++++++++ 4 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch diff --git a/build-data/paper.at b/build-data/paper.at index bb447c721..4945a796a 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -504,6 +504,7 @@ public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG public net.minecraft.world.item.JukeboxSongPlayer song public net.minecraft.world.item.MapItem createNewSavedData(Lnet/minecraft/world/level/Level;IIIZZLnet/minecraft/resources/ResourceKey;)Lnet/minecraft/world/level/saveddata/maps/MapId; public net.minecraft.world.item.StandingAndWallBlockItem wallBlock +public net.minecraft.world.item.component.BundleContents$Mutable getMaxAmountToAdd(Lnet/minecraft/world/item/ItemStack;)I public net.minecraft.world.item.component.ItemContainerContents MAX_SIZE public net.minecraft.world.item.component.ItemContainerContents items public net.minecraft.world.item.context.UseOnContext (Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V diff --git a/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java b/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java index b2bcc8911..b84aaf7f3 100644 --- a/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java +++ b/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java @@ -93,5 +93,29 @@ public enum InventoryAction { * An unrecognized ClickType. */ UNKNOWN, + /** + * The first stack of items in the clicked bundle is moved to the cursor. + */ + PICKUP_FROM_BUNDLE, + /** + * All of the items on the clicked slot are moved into the bundle on the cursor. + */ + PICKUP_ALL_INTO_BUNDLE, + /** + * Some of the items on the clicked slot are moved into the bundle on the cursor. + */ + PICKUP_SOME_INTO_BUNDLE, + /** + * The first stack of items is moved to the clicked slot. + */ + PLACE_FROM_BUNDLE, + /** + * All of the items on the cursor are moved into the bundle in the clicked slot. + */ + PLACE_ALL_INTO_BUNDLE, + /** + * Some of the items on the cursor are moved into the bundle in the clicked slot. + */ + PLACE_SOME_INTO_BUNDLE, ; } 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 37ab47c80..7b1d2a2d2 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 @@ -2017,7 +2017,7 @@ this.player.containerMenu.sendAllDataToRemote(); } else if (!this.player.containerMenu.stillValid(this.player)) { LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); -@@ -1713,7 +_,313 @@ +@@ -1713,7 +_,341 @@ } else { boolean flag = packet.getStateId() != this.player.containerMenu.getStateId(); this.player.containerMenu.suppressRemoteUpdates(); @@ -2056,11 +2056,19 @@ + ItemStack cursor = this.player.containerMenu.getCarried(); + if (clickedItem.isEmpty()) { + if (!cursor.isEmpty()) { -+ action = packet.getButtonNum() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; ++ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() != 0) { ++ action = cursor.get(DataComponents.BUNDLE_CONTENTS).isEmpty() ? InventoryAction.NOTHING : InventoryAction.PLACE_FROM_BUNDLE; ++ } else { ++ action = packet.getButtonNum() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; ++ } + } + } else if (slot.mayPickup(this.player)) { + if (cursor.isEmpty()) { -+ action = packet.getButtonNum() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; ++ if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() != 0) { ++ action = slot.getItem().get(DataComponents.BUNDLE_CONTENTS).isEmpty() ? InventoryAction.NOTHING : InventoryAction.PICKUP_FROM_BUNDLE; ++ } else { ++ action = packet.getButtonNum() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; ++ } + } else if (slot.mayPlace(cursor)) { + if (ItemStack.isSameItemSameComponents(clickedItem, cursor)) { + int toPlace = packet.getButtonNum() == 0 ? cursor.getCount() : 1; @@ -2076,7 +2084,27 @@ + action = InventoryAction.PLACE_SOME; + } + } else if (cursor.getCount() <= slot.getMaxStackSize()) { -+ action = InventoryAction.SWAP_WITH_CURSOR; ++ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() == 0) { ++ int toPickup = cursor.get(DataComponents.BUNDLE_CONTENTS).getMaxAmountToAdd(slot.getItem()); ++ if (toPickup >= slot.getItem().getCount()) { ++ action = InventoryAction.PICKUP_ALL_INTO_BUNDLE; ++ } else if (toPickup == 0) { ++ action = InventoryAction.NOTHING; ++ } else { ++ action = InventoryAction.PICKUP_SOME_INTO_BUNDLE; ++ } ++ } else if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() == 0) { ++ int toPickup = slot.getItem().get(DataComponents.BUNDLE_CONTENTS).getMaxAmountToAdd(cursor); ++ if (toPickup >= cursor.getCount()) { ++ action = InventoryAction.PLACE_ALL_INTO_BUNDLE; ++ } else if (toPickup == 0) { ++ action = InventoryAction.NOTHING; ++ } else { ++ action = InventoryAction.PLACE_SOME_INTO_BUNDLE; ++ } ++ } else { ++ action = InventoryAction.SWAP_WITH_CURSOR; ++ } + } + } else if (ItemStack.isSameItemSameComponents(cursor, clickedItem)) { + if (clickedItem.getCount() >= 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch new file mode 100644 index 000000000..cc4795690 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/item/component/BundleContents.java ++++ b/net/minecraft/world/item/component/BundleContents.java +@@ -76,6 +_,12 @@ + return !stack.isEmpty() && stack.getItem().canFitInsideContainerItems(); + } + ++ // Paper start - correct bundle inventory action ++ public int getMaxAmountToAdd(final ItemStack stack) { ++ return Mutable.getMaxAmountToAdd(stack, this.weight); ++ } ++ // Paper end - correct bundle inventory action ++ + public int getNumberOfItemsToShow() { + int size = this.size(); + int i = size > 12 ? 11 : 12; +@@ -171,7 +_,13 @@ + } + + public int getMaxAmountToAdd(ItemStack stack) { +- Fraction fraction = Fraction.ONE.subtract(this.weight); ++ // Paper start - correct bundle inventory action ++ // Static overload to easily compute this value without the need for an instance of mutable. ++ return getMaxAmountToAdd(stack, this.weight); ++ } ++ static int getMaxAmountToAdd(final ItemStack stack, final Fraction weight) { ++ Fraction fraction = Fraction.ONE.subtract(weight); ++ // Paper end - correct bundle inventory action + return Math.max(fraction.divideBy(BundleContents.getWeight(stack)).intValue(), 0); + } + From ac3aaa248b756c0c2d3dc91d80325bb931f914ba Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 11 Jan 2025 11:02:28 -0800 Subject: [PATCH 030/203] Don't use delayed registries in impl anywhere (#11918) --- paper-api/src/main/java/org/bukkit/Art.java | 13 ++++--- paper-api/src/main/java/org/bukkit/Fluid.java | 3 +- .../src/main/java/org/bukkit/JukeboxSong.java | 4 +- .../main/java/org/bukkit/MusicInstrument.java | 4 +- paper-api/src/main/java/org/bukkit/Sound.java | 3 +- .../main/java/org/bukkit/UnsafeValues.java | 3 +- .../java/org/bukkit/attribute/Attribute.java | 3 +- .../src/main/java/org/bukkit/block/Biome.java | 11 +++--- .../java/org/bukkit/block/banner/Pattern.java | 3 +- .../org/bukkit/block/banner/PatternType.java | 7 ++-- .../java/org/bukkit/damage/DamageType.java | 6 ++- .../org/bukkit/enchantments/Enchantment.java | 4 +- .../src/main/java/org/bukkit/entity/Wolf.java | 4 +- .../bukkit/generator/structure/Structure.java | 6 ++- .../java/org/bukkit/inventory/ItemStack.java | 3 +- .../inventory/meta/trim/TrimMaterial.java | 4 +- .../inventory/meta/trim/TrimPattern.java | 4 +- .../java/org/bukkit/potion/PotionEffect.java | 3 +- .../datacomponent/PaperDataComponentType.java | 3 +- .../item/PaperBannerPatternLayers.java | 3 +- .../io/papermc/paper/util/Holderable.java | 5 ++- .../java/org/bukkit/craftbukkit/CraftArt.java | 5 +-- .../org/bukkit/craftbukkit/CraftFluid.java | 3 +- .../bukkit/craftbukkit/CraftGameEvent.java | 3 +- .../bukkit/craftbukkit/CraftJukeboxSong.java | 3 +- .../craftbukkit/CraftMusicInstrument.java | 8 ++-- .../org/bukkit/craftbukkit/CraftRegistry.java | 39 +++++++++---------- .../org/bukkit/craftbukkit/CraftSound.java | 3 +- .../org/bukkit/craftbukkit/CraftWorld.java | 4 +- .../craftbukkit/attribute/CraftAttribute.java | 5 ++- .../bukkit/craftbukkit/block/CraftBanner.java | 3 +- .../bukkit/craftbukkit/block/CraftBiome.java | 3 +- .../craftbukkit/block/CraftBlockType.java | 2 +- .../block/banner/CraftPatternType.java | 5 +-- .../craftbukkit/damage/CraftDamageType.java | 3 +- .../enchantments/CraftEnchantment.java | 5 ++- .../bukkit/craftbukkit/entity/CraftCat.java | 3 +- .../craftbukkit/entity/CraftEntityType.java | 3 +- .../bukkit/craftbukkit/entity/CraftFrog.java | 3 +- .../craftbukkit/entity/CraftVillager.java | 6 +-- .../bukkit/craftbukkit/entity/CraftWolf.java | 3 +- .../generator/structure/CraftStructure.java | 3 +- .../structure/CraftStructureType.java | 3 +- .../craftbukkit/inventory/CraftItemType.java | 2 +- .../craftbukkit/inventory/CraftMenuType.java | 4 +- .../inventory/CraftMetaBanner.java | 3 +- .../inventory/trim/CraftTrimMaterial.java | 8 ++-- .../inventory/trim/CraftTrimPattern.java | 8 ++-- .../craftbukkit/legacy/enums/EnumEvil.java | 1 + .../craftbukkit/map/CraftMapCursor.java | 3 +- .../potion/CraftPotionEffectType.java | 3 +- .../craftbukkit/potion/CraftPotionType.java | 3 +- .../craftbukkit/util/CraftMagicNumbers.java | 9 +---- .../org/bukkit/registry/PerRegistryTest.java | 4 +- .../registry/RegistryConversionTest.java | 13 ++++--- 55 files changed, 145 insertions(+), 133 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Art.java b/paper-api/src/main/java/org/bukkit/Art.java index c06204489..82daa6941 100644 --- a/paper-api/src/main/java/org/bukkit/Art.java +++ b/paper-api/src/main/java/org/bukkit/Art.java @@ -2,12 +2,13 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryBuilderFactory; +import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider; import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; import java.util.Locale; import java.util.function.Consumer; -import org.bukkit.packs.DataPack; import org.bukkit.util.OldEnum; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -18,8 +19,8 @@ import org.jetbrains.annotations.Nullable; *

* The arts listed in this interface are present in the default server * or can be enabled via a {@link FeatureFlag}. - * There may be additional arts present in the server, for example from a {@link DataPack} - * which can be accessed via {@link Registry#ART}. + * There may be additional arts present in the server, for example from a {@link io.papermc.paper.datapack.Datapack} + * which can be accessed via {@link RegistryAccess#registryAccess()} and {@link RegistryKey#PAINTING_VARIANT}. */ public interface Art extends OldEnum, Keyed { @@ -87,7 +88,7 @@ public interface Art extends OldEnum, Keyed { @NotNull private static Art getArt(@NotNull String key) { - return Registry.ART.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.PAINTING_VARIANT).getOrThrow(NamespacedKey.minecraft(key)); } /** @@ -189,7 +190,7 @@ public interface Art extends OldEnum, Keyed { static Art getByName(@NotNull String name) { Preconditions.checkArgument(name != null, "Name cannot be null"); - return Bukkit.getUnsafe().get(Registry.ART, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + return Bukkit.getUnsafe().get(RegistryKey.PAINTING_VARIANT, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); } /** @@ -200,7 +201,7 @@ public interface Art extends OldEnum, Keyed { @NotNull @Deprecated(since = "1.21.3", forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.22") // Paper - will be removed via asm-utils static Art valueOf(@NotNull String name) { - Art art = Bukkit.getUnsafe().get(Registry.ART, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Art art = Bukkit.getUnsafe().get(RegistryKey.PAINTING_VARIANT, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); Preconditions.checkArgument(art != null, "No art found with the name %s", name); return art; } diff --git a/paper-api/src/main/java/org/bukkit/Fluid.java b/paper-api/src/main/java/org/bukkit/Fluid.java index a3ff4fefa..45a095f16 100644 --- a/paper-api/src/main/java/org/bukkit/Fluid.java +++ b/paper-api/src/main/java/org/bukkit/Fluid.java @@ -2,6 +2,7 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import org.bukkit.util.OldEnum; import org.jetbrains.annotations.NotNull; @@ -45,7 +46,7 @@ public interface Fluid extends OldEnum, Keyed { @NotNull @Deprecated(since = "1.21.3", forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.22") // Paper - will be removed via asm-utils static Fluid valueOf(@NotNull String name) { - Fluid fluid = Bukkit.getUnsafe().get(Registry.FLUID, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Fluid fluid = Bukkit.getUnsafe().get(RegistryKey.FLUID, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); Preconditions.checkArgument(fluid != null, "No fluid found with the name %s", name); return fluid; } diff --git a/paper-api/src/main/java/org/bukkit/JukeboxSong.java b/paper-api/src/main/java/org/bukkit/JukeboxSong.java index c6feb13c7..7e3dca502 100644 --- a/paper-api/src/main/java/org/bukkit/JukeboxSong.java +++ b/paper-api/src/main/java/org/bukkit/JukeboxSong.java @@ -1,5 +1,7 @@ package org.bukkit; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -31,7 +33,7 @@ public interface JukeboxSong extends Keyed, Translatable { @NotNull private static JukeboxSong get(@NotNull String key) { - return Registry.JUKEBOX_SONG.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.JUKEBOX_SONG).getOrThrow(NamespacedKey.minecraft(key)); } // Paper start - adventure diff --git a/paper-api/src/main/java/org/bukkit/MusicInstrument.java b/paper-api/src/main/java/org/bukkit/MusicInstrument.java index d41892af5..bfe64b367 100644 --- a/paper-api/src/main/java/org/bukkit/MusicInstrument.java +++ b/paper-api/src/main/java/org/bukkit/MusicInstrument.java @@ -1,6 +1,8 @@ package org.bukkit; import com.google.common.collect.Lists; +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; @@ -44,7 +46,7 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran @NotNull private static MusicInstrument getInstrument(@NotNull String key) { - return Registry.INSTRUMENT.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.INSTRUMENT).getOrThrow(NamespacedKey.minecraft(key)); } // Paper start - deprecate getKey diff --git a/paper-api/src/main/java/org/bukkit/Sound.java b/paper-api/src/main/java/org/bukkit/Sound.java index 70d6dedca..e2fb7cfba 100644 --- a/paper-api/src/main/java/org/bukkit/Sound.java +++ b/paper-api/src/main/java/org/bukkit/Sound.java @@ -2,6 +2,7 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import org.bukkit.packs.DataPack; import org.bukkit.util.OldEnum; @@ -1687,7 +1688,7 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. @NotNull @Deprecated(since = "1.21.3") static Sound valueOf(@NotNull String name) { - Sound sound = Bukkit.getUnsafe().get(Registry.SOUNDS, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Sound sound = Bukkit.getUnsafe().get(RegistryKey.SOUND_EVENT, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); if (sound != null) { return sound; } diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java index 29838175a..de34d0684 100644 --- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java +++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java @@ -2,6 +2,7 @@ package org.bukkit; import com.google.common.collect.Multimap; import io.papermc.paper.entity.EntitySerializationFlag; +import io.papermc.paper.registry.RegistryKey; import org.bukkit.advancement.Advancement; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; @@ -140,7 +141,7 @@ public interface UnsafeValues { String get(Class aClass, String value); @ApiStatus.Internal - B get(Registry registry, NamespacedKey key); + B get(RegistryKey registry, NamespacedKey key); @ApiStatus.Internal Biome getCustomBiome(); diff --git a/paper-api/src/main/java/org/bukkit/attribute/Attribute.java b/paper-api/src/main/java/org/bukkit/attribute/Attribute.java index 273ef25fe..978b0e779 100644 --- a/paper-api/src/main/java/org/bukkit/attribute/Attribute.java +++ b/paper-api/src/main/java/org/bukkit/attribute/Attribute.java @@ -2,6 +2,7 @@ package org.bukkit.attribute; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import org.bukkit.Bukkit; import org.bukkit.Keyed; @@ -158,7 +159,7 @@ public interface Attribute extends OldEnum, Keyed, Translatable, net. @NotNull @Deprecated(since = "1.21.3", forRemoval = true) @org.jetbrains.annotations.ApiStatus.ScheduledForRemoval(inVersion = "1.22") // Paper - will be removed via asm-utils static Attribute valueOf(@NotNull String name) { - Attribute attribute = Bukkit.getUnsafe().get(Registry.ATTRIBUTE, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Attribute attribute = Bukkit.getUnsafe().get(RegistryKey.ATTRIBUTE, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); Preconditions.checkArgument(attribute != null, "No attribute found with the name %s", name); return attribute; } diff --git a/paper-api/src/main/java/org/bukkit/block/Biome.java b/paper-api/src/main/java/org/bukkit/block/Biome.java index 20fc2b30f..1387559c3 100644 --- a/paper-api/src/main/java/org/bukkit/block/Biome.java +++ b/paper-api/src/main/java/org/bukkit/block/Biome.java @@ -2,13 +2,14 @@ package org.bukkit.block; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import org.bukkit.Bukkit; import org.bukkit.FeatureFlag; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.Registry; -import org.bukkit.packs.DataPack; import org.bukkit.util.OldEnum; import org.jetbrains.annotations.NotNull; @@ -17,8 +18,8 @@ import org.jetbrains.annotations.NotNull; *

* The Biomes listed in this interface are present in the default server * or can be enabled via a {@link FeatureFlag}. - * There may be additional biomes present in the server, for example from a {@link DataPack} - * which can be accessed via {@link Registry#BIOME}. + * There may be additional biomes present in the server, for example from a {@link io.papermc.paper.datapack.Datapack} + * which can be accessed via {@link io.papermc.paper.registry.RegistryAccess#getRegistry(RegistryKey)} and {@link RegistryKey#BIOME}. */ public interface Biome extends OldEnum, Keyed, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations @@ -98,7 +99,7 @@ public interface Biome extends OldEnum, Keyed, net.kyori.adventure.transl @NotNull private static Biome getBiome(@NotNull String key) { - return Registry.BIOME.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.BIOME).getOrThrow(NamespacedKey.minecraft(key)); } /** @@ -113,7 +114,7 @@ public interface Biome extends OldEnum, Keyed, net.kyori.adventure.transl return Biome.CUSTOM; } - Biome biome = Bukkit.getUnsafe().get(Registry.BIOME, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); + Biome biome = Bukkit.getUnsafe().get(RegistryKey.BIOME, NamespacedKey.fromString(name.toLowerCase(Locale.ROOT))); Preconditions.checkArgument(biome != null, "No biome found with the name %s", name); return biome; } diff --git a/paper-api/src/main/java/org/bukkit/block/banner/Pattern.java b/paper-api/src/main/java/org/bukkit/block/banner/Pattern.java index de815683b..d760d500f 100644 --- a/paper-api/src/main/java/org/bukkit/block/banner/Pattern.java +++ b/paper-api/src/main/java/org/bukkit/block/banner/Pattern.java @@ -2,6 +2,7 @@ package org.bukkit.block.banner; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; +import io.papermc.paper.registry.RegistryKey; import java.util.Map; import java.util.NoSuchElementException; import org.bukkit.Bukkit; @@ -45,7 +46,7 @@ public class Pattern implements ConfigurationSerializable { PatternType patternType = PatternType.getByIdentifier(value); if (patternType == null) { - patternType = Bukkit.getUnsafe().get(Registry.BANNER_PATTERN, NamespacedKey.fromString(value)); + patternType = Bukkit.getUnsafe().get(RegistryKey.BANNER_PATTERN, NamespacedKey.fromString(value)); } Preconditions.checkNotNull(patternType, "Pattern type for key %s cannot be null", value); diff --git a/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java b/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java index 24b58ed80..444f128e8 100644 --- a/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java +++ b/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java @@ -2,6 +2,8 @@ package org.bukkit.block.banner; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; @@ -95,8 +97,7 @@ public interface PatternType extends OldEnum, Keyed { * * @param identifier the identifier * @return the matched pattern type or null - * @see Registry#BANNER_PATTERN - * @deprecated magic value, use {@link Registry#get(NamespacedKey)} instead + * @deprecated magic value, use {@link Registry#get(NamespacedKey)} instead with {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} and {@link io.papermc.paper.registry.RegistryKey#BANNER_PATTERN} */ @Contract("null -> null") @Nullable @@ -117,7 +118,7 @@ public interface PatternType extends OldEnum, Keyed { @NotNull private static PatternType getType(@NotNull String key) { - return Registry.BANNER_PATTERN.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.BANNER_PATTERN).getOrThrow(NamespacedKey.minecraft(key)); } /** diff --git a/paper-api/src/main/java/org/bukkit/damage/DamageType.java b/paper-api/src/main/java/org/bukkit/damage/DamageType.java index 14f90d8d4..b74846c77 100644 --- a/paper-api/src/main/java/org/bukkit/damage/DamageType.java +++ b/paper-api/src/main/java/org/bukkit/damage/DamageType.java @@ -1,5 +1,7 @@ package org.bukkit.damage; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -12,7 +14,7 @@ import org.jetbrains.annotations.NotNull; *

* Constants in this class include the base types provided by the vanilla * server. Data packs are capable of registering more types of damage which may - * be obtained through the {@link Registry#DAMAGE_TYPE}. + * be obtained through {@link io.papermc.paper.registry.RegistryAccess#getRegistry(RegistryKey)} and {@link RegistryKey#DAMAGE_TYPE}. * * @see Minecraft Wiki */ @@ -71,7 +73,7 @@ public interface DamageType extends Keyed, Translatable { @NotNull private static DamageType getDamageType(@NotNull String key) { - return Registry.DAMAGE_TYPE.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.DAMAGE_TYPE).getOrThrow(NamespacedKey.minecraft(key)); } /** diff --git a/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java b/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java index a824ac90e..288123c31 100644 --- a/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java +++ b/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java @@ -1,6 +1,8 @@ package org.bukkit.enchantments; import com.google.common.collect.Lists; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; @@ -229,7 +231,7 @@ public abstract class Enchantment implements Keyed, Translatable, net.kyori.adve @NotNull private static Enchantment getEnchantment(@NotNull String key) { - return Registry.ENCHANTMENT.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.ENCHANTMENT).getOrThrow(NamespacedKey.minecraft(key)); } /** 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 c73489f4b..346fdddd2 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Wolf.java +++ b/paper-api/src/main/java/org/bukkit/entity/Wolf.java @@ -1,5 +1,7 @@ package org.bukkit.entity; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import org.bukkit.DyeColor; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; @@ -105,7 +107,7 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar @NotNull private static Variant getVariant(@NotNull String key) { - return Registry.WOLF_VARIANT.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.WOLF_VARIANT).getOrThrow(NamespacedKey.minecraft(key)); } } } diff --git a/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java b/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java index b6920f834..228df69a6 100644 --- a/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java +++ b/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java @@ -1,5 +1,7 @@ package org.bukkit.generator.structure; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -10,7 +12,7 @@ import org.jetbrains.annotations.NotNull; * * Listed structures are present in the default server. Depending on the server * there might be additional structures present (for example structures added by - * data packs), which can be received via {@link Registry#STRUCTURE}. + * data packs), which can be received via {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} and {@link io.papermc.paper.registry.RegistryKey#STRUCTURE}. */ public abstract class Structure implements Keyed { @@ -51,7 +53,7 @@ public abstract class Structure implements Keyed { @NotNull private static Structure getStructure(@NotNull String name) { - return Registry.STRUCTURE.getOrThrow(NamespacedKey.minecraft(name)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.STRUCTURE).getOrThrow(NamespacedKey.minecraft(name)); } /** 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 d95d0d6a8..55457c753 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -2,6 +2,7 @@ package org.bukkit.inventory; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; +import io.papermc.paper.registry.RegistryKey; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; @@ -543,7 +544,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat stringKey = Bukkit.getUnsafe().get(Enchantment.class, stringKey); NamespacedKey key = NamespacedKey.fromString(stringKey.toLowerCase(Locale.ROOT)); - Enchantment enchantment = Bukkit.getUnsafe().get(Registry.ENCHANTMENT, key); + Enchantment enchantment = Bukkit.getUnsafe().get(RegistryKey.ENCHANTMENT, key); if ((enchantment != null) && (entry.getValue() instanceof Integer)) { result.addUnsafeEnchantment(enchantment, (Integer) entry.getValue()); diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java index 7e8a4b4ec..0910dd287 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java @@ -1,5 +1,7 @@ package org.bukkit.inventory.meta.trim; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import org.bukkit.Keyed; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -59,7 +61,7 @@ public interface TrimMaterial extends Keyed, Translatable { @NotNull private static TrimMaterial getTrimMaterial(@NotNull String key) { - return Registry.TRIM_MATERIAL.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_MATERIAL).getOrThrow(NamespacedKey.minecraft(key)); } // Paper start - adventure diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java index b2fa0d565..9360e27b0 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java @@ -1,5 +1,7 @@ package org.bukkit.inventory.meta.trim; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import org.bukkit.Keyed; import org.bukkit.Material; import org.bukkit.NamespacedKey; @@ -87,7 +89,7 @@ public interface TrimPattern extends Keyed, Translatable { @NotNull private static TrimPattern getTrimPattern(@NotNull String key) { - return Registry.TRIM_PATTERN.getOrThrow(NamespacedKey.minecraft(key)); + return RegistryAccess.registryAccess().getRegistry(RegistryKey.TRIM_PATTERN).getOrThrow(NamespacedKey.minecraft(key)); } // Paper start - adventure diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionEffect.java b/paper-api/src/main/java/org/bukkit/potion/PotionEffect.java index ab8f3c089..7cac918e0 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionEffect.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionEffect.java @@ -2,6 +2,7 @@ package org.bukkit.potion; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; +import io.papermc.paper.registry.RegistryKey; import java.util.Map; import java.util.NoSuchElementException; import org.bukkit.Bukkit; @@ -175,7 +176,7 @@ public class PotionEffect implements ConfigurationSerializable { private static PotionEffectType getEffectType(@NotNull Map map) { PotionEffectType effect; if (map.get(TYPE) instanceof String value) { - effect = Bukkit.getUnsafe().get(Registry.EFFECT, NamespacedKey.fromString(value)); + effect = Bukkit.getUnsafe().get(RegistryKey.MOB_EFFECT, NamespacedKey.fromString(value)); } else { int type = getInt(map, TYPE); effect = PotionEffectType.getById(type); diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java index e2fcf870b..7ec9b765f 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java @@ -7,7 +7,6 @@ import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; import org.jspecify.annotations.Nullable; @@ -23,7 +22,7 @@ public abstract class PaperDataComponentType implements DataComponentTyp } public static DataComponentType minecraftToBukkit(final net.minecraft.core.component.DataComponentType type) { - return CraftRegistry.minecraftToBukkit(type, Registries.DATA_COMPONENT_TYPE, Registry.DATA_COMPONENT_TYPE); + return CraftRegistry.minecraftToBukkit(type, Registries.DATA_COMPONENT_TYPE); } public static Set minecraftToBukkit(final Set> nmsTypes) { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java index ca49c2d2e..9963cbf9f 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBannerPatternLayers.java @@ -1,6 +1,5 @@ package io.papermc.paper.datacomponent.item; -import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.util.MCUtil; import java.util.List; @@ -20,7 +19,7 @@ public record PaperBannerPatternLayers( private static List convert(final net.minecraft.world.level.block.entity.BannerPatternLayers nmsPatterns) { return MCUtil.transformUnmodifiable(nmsPatterns.layers(), input -> { - final Optional type = CraftRegistry.unwrapAndConvertHolder(RegistryAccess.registryAccess().getRegistry(RegistryKey.BANNER_PATTERN), input.pattern()); + final Optional type = CraftRegistry.unwrapAndConvertHolder(RegistryKey.BANNER_PATTERN, input.pattern()); return new Pattern(Objects.requireNonNull(DyeColor.getByWoolData((byte) input.color().getId())), type.orElseThrow(() -> new IllegalStateException("Inlined banner patterns are not supported yet in the API!"))); }); } diff --git a/paper-server/src/main/java/io/papermc/paper/util/Holderable.java b/paper-server/src/main/java/io/papermc/paper/util/Holderable.java index c0115e0a3..5958c6fd4 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/Holderable.java +++ b/paper-server/src/main/java/io/papermc/paper/util/Holderable.java @@ -4,6 +4,8 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import net.kyori.adventure.key.Key; import net.minecraft.core.Holder; import net.minecraft.resources.RegistryOps; @@ -25,7 +27,8 @@ public interface Holderable extends Handleable { return this.getHolder().value(); } - static @Nullable T fromBukkitSerializationObject(final Object deserialized, final Codec> codec, final Registry registry) { // TODO remove Keyed + static @Nullable T fromBukkitSerializationObject(final Object deserialized, final Codec> codec, final RegistryKey registryKey) { // TODO remove Keyed + final Registry registry = RegistryAccess.registryAccess().getRegistry(registryKey); return switch (deserialized) { case @Subst("key:value") final String string -> { if (!(Key.parseable(string))) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftArt.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftArt.java index d4edaea71..b784da2a5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftArt.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftArt.java @@ -7,18 +7,17 @@ import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.decoration.PaintingVariant; import org.bukkit.Art; -import org.bukkit.Registry; public class CraftArt extends OldEnumHolderable implements Art { private static int count = 0; public static Art minecraftToBukkit(PaintingVariant minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.PAINTING_VARIANT, Registry.ART); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.PAINTING_VARIANT); } public static Art minecraftHolderToBukkit(Holder minecraft) { - return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.ART); + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.PAINTING_VARIANT); } public static PaintingVariant bukkitToMinecraft(Art bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java index 6cbd9d313..f01fadad7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftFluid.java @@ -4,7 +4,6 @@ import java.util.Locale; import net.minecraft.core.registries.Registries; import org.bukkit.Fluid; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.util.Handleable; import org.jetbrains.annotations.NotNull; @@ -13,7 +12,7 @@ public class CraftFluid implements Fluid, Handleable { public static GameEvent minecraftToBukkit(net.minecraft.world.level.gameevent.GameEvent minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.GAME_EVENT, Registry.GAME_EVENT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.GAME_EVENT); } public static net.minecraft.world.level.gameevent.GameEvent bukkitToMinecraft(GameEvent bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftJukeboxSong.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftJukeboxSong.java index 2772c19f5..e75c045e3 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftJukeboxSong.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftJukeboxSong.java @@ -6,14 +6,13 @@ import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.contents.TranslatableContents; import org.bukkit.JukeboxSong; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.util.Handleable; import org.jetbrains.annotations.NotNull; public class CraftJukeboxSong implements JukeboxSong, Handleable { public static JukeboxSong minecraftToBukkit(net.minecraft.world.item.JukeboxSong minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.JUKEBOX_SONG, Registry.JUKEBOX_SONG); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.JUKEBOX_SONG); } public static JukeboxSong minecraftHolderToBukkit(Holder minecraft) { 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 7ad11769a..b72a07064 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.util.Holderable; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -8,17 +9,16 @@ import net.minecraft.world.item.Instrument; import org.bukkit.MusicInstrument; import org.bukkit.NamespacedKey; import org.bukkit.Registry; -import org.bukkit.craftbukkit.util.Handleable; import org.jetbrains.annotations.NotNull; public class CraftMusicInstrument extends MusicInstrument implements io.papermc.paper.util.Holderable { public static MusicInstrument minecraftToBukkit(Instrument minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.INSTRUMENT, Registry.INSTRUMENT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.INSTRUMENT); } public static MusicInstrument minecraftHolderToBukkit(Holder minecraft) { - return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.INSTRUMENT); // Paper - switch to Holder + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.INSTRUMENT); // Paper - switch to Holder } public static Instrument bukkitToMinecraft(MusicInstrument bukkit) { @@ -38,7 +38,7 @@ public class CraftMusicInstrument extends MusicInstrument implements io.papermc. public static MusicInstrument stringToBukkit(Object string) { // Paper - switch to Holder Preconditions.checkArgument(string != null); - return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(string, Instrument.CODEC, Registry.INSTRUMENT); // Paper - switch to Holder + return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(string, Instrument.CODEC, RegistryKey.INSTRUMENT); // Paper - switch to Holder } // Paper start - switch to Holder diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index b3f781c0c..fcf177b3c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -1,12 +1,15 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.set.NamedRegistryKeySetImpl; import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.util.Holderable; -import java.util.Collection; import io.papermc.paper.util.MCUtil; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -15,7 +18,6 @@ import java.util.function.BiFunction; import java.util.stream.Stream; import net.minecraft.core.Holder; import net.minecraft.core.HolderOwner; -import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; @@ -30,14 +32,14 @@ import org.jetbrains.annotations.NotNull; public class CraftRegistry implements Registry { - private static RegistryAccess registry; + private static net.minecraft.core.RegistryAccess registry; - public static void setMinecraftRegistry(RegistryAccess registry) { + public static void setMinecraftRegistry(final net.minecraft.core.RegistryAccess registry) { Preconditions.checkState(CraftRegistry.registry == null, "Registry already set"); CraftRegistry.registry = registry; } - public static RegistryAccess getMinecraftRegistry() { + public static net.minecraft.core.RegistryAccess getMinecraftRegistry() { return CraftRegistry.registry; } @@ -49,16 +51,15 @@ public class CraftRegistry implements Registry { * Usage note: Only use this method to delegate the conversion methods from the individual Craft classes to here. * Do not use it in other parts of CraftBukkit, use the methods in the respective Craft classes instead. * - * @param minecraft the minecraft representation + * @param minecraft the minecraft representation * @param registryKey the registry key of the minecraft registry to use - * @param bukkitRegistry the bukkit registry to use * @return the bukkit representation of the minecraft value */ - public static B minecraftToBukkit(M minecraft, ResourceKey> registryKey, Registry bukkitRegistry) { + public static B minecraftToBukkit(M minecraft, ResourceKey> registryKey) { Preconditions.checkArgument(minecraft != null); net.minecraft.core.Registry registry = CraftRegistry.getMinecraftRegistry(registryKey); - // Paper start - support direct Holders + final Registry bukkitRegistry = RegistryAccess.registryAccess().getRegistry(PaperRegistries.registryFromNms(registryKey)); final java.util.Optional> resourceKey = registry.getResourceKey(minecraft); if (resourceKey.isEmpty() && bukkitRegistry instanceof final CraftRegistry craftRegistry && craftRegistry.supportsDirectHolders()) { return ((CraftRegistry) bukkitRegistry).convertDirectHolder(Holder.direct(minecraft)); @@ -66,17 +67,16 @@ public class CraftRegistry implements Registry { throw new IllegalStateException(String.format("Cannot convert '%s' to bukkit representation, since it is not registered.", minecraft)); } final B bukkit = bukkitRegistry.get(CraftNamespacedKey.fromMinecraft(resourceKey.get().location())); - // Paper end - support direct Holders Preconditions.checkArgument(bukkit != null); return bukkit; } - // Paper start - support direct Holders - public static B minecraftHolderToBukkit(final Holder minecraft, final Registry bukkitRegistry) { + public static B minecraftHolderToBukkit(final Holder minecraft, final ResourceKey> registryKey) { Preconditions.checkArgument(minecraft != null); + final Registry bukkitRegistry = RegistryAccess.registryAccess().getRegistry(PaperRegistries.registryFromNms(registryKey)); final B bukkit = switch (minecraft) { case final Holder.Direct direct -> { if (!(bukkitRegistry instanceof final CraftRegistry craftRegistry) || !craftRegistry.supportsDirectHolders()) { @@ -84,14 +84,13 @@ public class CraftRegistry implements Registry { } yield ((CraftRegistry) bukkitRegistry).convertDirectHolder(direct); } - case final Holder.Reference reference -> bukkitRegistry.get(io.papermc.paper.util.MCUtil.fromResourceKey(reference.key())); + case final Holder.Reference reference -> bukkitRegistry.get(MCUtil.fromResourceKey(reference.key())); default -> throw new IllegalArgumentException("Unknown holder: " + minecraft); }; Preconditions.checkArgument(bukkit != null); return bukkit; } - // Paper end - support direct Holders /** * Usage note: Only use this method to delegate the conversion methods from the individual Craft classes to here. @@ -125,13 +124,10 @@ public class CraftRegistry implements Registry { } // Paper start - fixup upstream being dum - public static java.util.Optional unwrapAndConvertHolder(final io.papermc.paper.registry.RegistryKey registryKey, final Holder value) { - return unwrapAndConvertHolder(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(registryKey), value); - } - - public static java.util.Optional unwrapAndConvertHolder(final Registry registry, final Holder value) { + public static Optional unwrapAndConvertHolder(final RegistryKey registryKey, final Holder value) { + final Registry registry = RegistryAccess.registryAccess().getRegistry(registryKey); if (registry instanceof CraftRegistry craftRegistry && craftRegistry.supportsDirectHolders() && value.kind() == Holder.Kind.DIRECT) { - return java.util.Optional.of(((CraftRegistry) registry).convertDirectHolder(value)); + return Optional.of(((CraftRegistry) registry).convertDirectHolder(value)); } return value.unwrapKey().map(key -> registry.get(CraftNamespacedKey.fromMinecraft(key.location()))); } @@ -140,7 +136,8 @@ public class CraftRegistry implements Registry { // Paper - move to PaperRegistries // Paper - NOTE: As long as all uses of the method below relate to *serialization* via ConfigurationSerializable, it's fine - public static B get(Registry bukkit, NamespacedKey namespacedKey, ApiVersion apiVersion) { + public static B get(RegistryKey bukkitKey, NamespacedKey namespacedKey, ApiVersion apiVersion) { + final Registry bukkit = RegistryAccess.registryAccess().getRegistry(bukkitKey); if (bukkit instanceof CraftRegistry craft) { return craft.get(craft.serializationUpdater.apply(namespacedKey, apiVersion)); // Paper } 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 451fe79b1..9cfbe2390 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftSound.java @@ -4,7 +4,6 @@ import io.papermc.paper.util.OldEnumHolderable; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.sounds.SoundEvent; -import org.bukkit.Registry; import org.bukkit.Sound; public class CraftSound extends OldEnumHolderable implements Sound { @@ -12,7 +11,7 @@ public class CraftSound extends OldEnumHolderable implements private static int count = 0; public static Sound minecraftToBukkit(SoundEvent minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.SOUND_EVENT, Registry.SOUNDS); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.SOUND_EVENT); } public static SoundEvent bukkitToMinecraft(Sound 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 281969314..ba32db69c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -6,6 +6,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.mojang.datafixers.util.Pair; import io.papermc.paper.FeatureHooks; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import java.io.File; @@ -2242,7 +2244,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public StructureSearchResult locateNearestStructure(Location origin, StructureType structureType, int radius, boolean findUnexplored) { List structures = new ArrayList<>(); - for (Structure structure : Registry.STRUCTURE) { + for (Structure structure : RegistryAccess.registryAccess().getRegistry(RegistryKey.STRUCTURE)) { if (structure.getStructureType() == structureType) { structures.add(structure); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java b/paper-server/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java index 0d04f0a34..1e7ea738f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttribute.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.attribute; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -18,7 +19,7 @@ public class CraftAttribute implements Attribute, Handleable minecraft) { @@ -36,7 +37,7 @@ public class CraftAttribute implements Attribute, Handleable implem for (int i = 0; i < banner.getPatterns().layers().size(); i++) { BannerPatternLayers.Layer p = banner.getPatterns().layers().get(i); // Paper start - fix upstream not handling inlined banner pattern - java.util.Optional type = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(org.bukkit.Registry.BANNER_PATTERN, p.pattern()); + java.util.Optional type = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(RegistryKey.BANNER_PATTERN, p.pattern()); if (type.isEmpty()) continue; this.patterns.add(new Pattern(DyeColor.getByWoolData((byte) p.color().getId()), type.get())); // Paper end - fix upstream not handling inlined banner pattern diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java index 4e535481c..55c99297a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java @@ -4,7 +4,6 @@ import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; @@ -15,7 +14,7 @@ public class CraftBiome implements Biome, Handleable minecraft) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java index 978e602c3..90fe14f10 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java @@ -49,7 +49,7 @@ public class CraftBlockType implements BlockType.Typed, } public static BlockType minecraftToBukkitNew(Block minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.BLOCK, Registry.BLOCK); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.BLOCK); } public static Block bukkitToMinecraftNew(BlockType bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/banner/CraftPatternType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/banner/CraftPatternType.java index 749024b25..5865892ad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/banner/CraftPatternType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/banner/CraftPatternType.java @@ -4,7 +4,6 @@ import io.papermc.paper.util.OldEnumHolderable; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.block.entity.BannerPattern; -import org.bukkit.Registry; import org.bukkit.block.banner.PatternType; import org.bukkit.craftbukkit.CraftRegistry; @@ -13,11 +12,11 @@ public class CraftPatternType extends OldEnumHolderable minecraft) { - return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.BANNER_PATTERN); + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.BANNER_PATTERN); } public static BannerPattern bukkitToMinecraft(PatternType bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java index d48641242..335077585 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java @@ -4,7 +4,6 @@ import com.google.common.base.Preconditions; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.damage.DamageEffect; @@ -120,6 +119,6 @@ public class CraftDamageType implements DamageType, Handleable { public static Enchantment minecraftToBukkit(net.minecraft.world.item.enchantment.Enchantment minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.ENCHANTMENT, Registry.ENCHANTMENT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.ENCHANTMENT); } public static Enchantment minecraftHolderToBukkit(Holder minecraft) { @@ -52,7 +53,7 @@ public class CraftEnchantment extends Enchantment implements Holderable handle; 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 88e876da7..1a09082fc 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 @@ -7,7 +7,6 @@ import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.animal.CatVariant; import org.bukkit.DyeColor; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.Handleable; @@ -55,7 +54,7 @@ public class CraftCat extends CraftTameableAnimal implements Cat { private static int count = 0; public static Type minecraftToBukkit(CatVariant minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.CAT_VARIANT, Registry.CAT_VARIANT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.CAT_VARIANT); } public static Type minecraftHolderToBukkit(Holder minecraft) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java index d230cbc26..47db45462 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityType.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; import java.util.Locale; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -61,6 +62,6 @@ public class CraftEntityType { NamespacedKey key = NamespacedKey.fromString(string); // Now also convert from when keys where saved - return CraftRegistry.get(Registry.ENTITY_TYPE, key, ApiVersion.CURRENT); + return CraftRegistry.get(RegistryKey.ENTITY_TYPE, key, ApiVersion.CURRENT); } } 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 ebf09c27e..58cacdc8f 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 @@ -7,7 +7,6 @@ import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.animal.FrogVariant; import net.minecraft.world.entity.animal.frog.Frog; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.Handleable; @@ -59,7 +58,7 @@ public class CraftFrog extends CraftAnimals implements org.bukkit.entity.Frog { private static int count = 0; public static Variant minecraftToBukkit(FrogVariant minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.FROG_VARIANT, Registry.FROG_VARIANT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.FROG_VARIANT); } public static Variant minecraftHolderToBukkit(Holder minecraft) { 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 8e895d6f8..aaddce10e 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 @@ -11,7 +11,6 @@ import net.minecraft.world.level.block.BedBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Location; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.CraftLocation; @@ -23,7 +22,6 @@ import org.bukkit.event.entity.EntityTransformEvent; // Paper start import com.destroystokyo.paper.entity.villager.Reputation; -import com.google.common.collect.Maps; import java.util.Map; import java.util.UUID; // Paper end @@ -177,7 +175,7 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { private static int count = 0; public static Type minecraftToBukkit(VillagerType minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.VILLAGER_TYPE, Registry.VILLAGER_TYPE); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.VILLAGER_TYPE); } public static VillagerType bukkitToMinecraft(Type bukkit) { @@ -258,7 +256,7 @@ public class CraftVillager extends CraftAbstractVillager implements Villager { private static int count = 0; public static Profession minecraftToBukkit(VillagerProfession minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.VILLAGER_PROFESSION, Registry.VILLAGER_PROFESSION); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.VILLAGER_PROFESSION); } public static VillagerProfession bukkitToMinecraft(Profession bukkit) { 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 ecd33b4ad..c1b7f1281 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 @@ -6,7 +6,6 @@ import net.minecraft.core.registries.Registries; import net.minecraft.world.entity.animal.WolfVariant; import org.bukkit.DyeColor; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.Handleable; @@ -81,7 +80,7 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { public static class CraftVariant implements Variant, Handleable { public static Variant minecraftToBukkit(WolfVariant minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.WOLF_VARIANT, Registry.WOLF_VARIANT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.WOLF_VARIANT); } public static Variant minecraftHolderToBukkit(Holder minecraft) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructure.java b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructure.java index 09fd00624..75f589e83 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructure.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructure.java @@ -4,7 +4,6 @@ import com.google.common.base.Suppliers; import java.util.function.Supplier; import net.minecraft.core.registries.Registries; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.generator.structure.Structure; @@ -13,7 +12,7 @@ import org.bukkit.generator.structure.StructureType; public class CraftStructure extends Structure implements Handleable { public static Structure minecraftToBukkit(net.minecraft.world.level.levelgen.structure.Structure minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.STRUCTURE, Registry.STRUCTURE); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.STRUCTURE); } public static net.minecraft.world.level.levelgen.structure.Structure bukkitToMinecraft(Structure bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructureType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructureType.java index 7199847c7..cd2d04c1b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructureType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/structure/CraftStructureType.java @@ -2,7 +2,6 @@ package org.bukkit.craftbukkit.generator.structure; import net.minecraft.core.registries.Registries; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.generator.structure.StructureType; @@ -10,7 +9,7 @@ import org.bukkit.generator.structure.StructureType; public class CraftStructureType extends StructureType implements Handleable> { public static StructureType minecraftToBukkit(net.minecraft.world.level.levelgen.structure.StructureType minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.STRUCTURE_TYPE, Registry.STRUCTURE_TYPE); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.STRUCTURE_TYPE); } public static net.minecraft.world.level.levelgen.structure.StructureType bukkitToMinecraft(StructureType bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java index b0da057ce..24ff46293 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemType.java @@ -51,7 +51,7 @@ public class CraftItemType implements ItemType.Typed, Han } public static ItemType minecraftToBukkitNew(Item minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.ITEM, Registry.ITEM); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.ITEM); } public static Item bukkitToMinecraftNew(ItemType bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java index fbde94b72..e4d81ef26 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java @@ -8,11 +8,9 @@ import net.minecraft.core.registries.Registries; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.inventory.AbstractContainerMenu; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.craftbukkit.inventory.util.CraftMenus; -import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.InventoryView; @@ -85,7 +83,7 @@ public class CraftMenuType implements MenuType.Typed } public static MenuType minecraftToBukkit(net.minecraft.world.inventory.MenuType minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.MENU, Registry.MENU); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.MENU); } public static MenuType minecraftHolderToBukkit(Holder> minecraft) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java index fdc0c1d73..30cc01cf1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.inventory; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import io.papermc.paper.registry.RegistryKey; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -42,7 +43,7 @@ public class CraftMetaBanner extends CraftMetaItem implements BannerMeta { for (int i = 0; i < Math.min(patterns.size(), 20); i++) { BannerPatternLayers.Layer p = patterns.get(i); DyeColor color = DyeColor.getByWoolData((byte) p.color().getId()); - PatternType pattern = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(org.bukkit.Registry.BANNER_PATTERN, p.pattern()).orElse(null); // Paper - fix upstream not handling inlined banner pattern + PatternType pattern = org.bukkit.craftbukkit.CraftRegistry.unwrapAndConvertHolder(RegistryKey.BANNER_PATTERN, p.pattern()).orElse(null); // Paper - fix upstream not handling inlined banner pattern if (color != null && pattern != null) { this.patterns.add(new Pattern(color, pattern)); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java index 77378a90f..d4905c329 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.inventory.trim; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.util.Holderable; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -8,18 +9,17 @@ import net.minecraft.network.chat.contents.TranslatableContents; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; -import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.inventory.meta.trim.TrimMaterial; import org.jetbrains.annotations.NotNull; public class CraftTrimMaterial implements TrimMaterial, io.papermc.paper.util.Holderable { // Paper - switch to Holder public static TrimMaterial minecraftToBukkit(net.minecraft.world.item.equipment.trim.TrimMaterial minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_MATERIAL, Registry.TRIM_MATERIAL); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_MATERIAL); } public static TrimMaterial minecraftHolderToBukkit(Holder minecraft) { - return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.TRIM_MATERIAL); // Paper - switch to Holder + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.TRIM_MATERIAL); // Paper - switch to Holder } public static net.minecraft.world.item.equipment.trim.TrimMaterial bukkitToMinecraft(TrimMaterial bukkit) { @@ -42,7 +42,7 @@ public class CraftTrimMaterial implements TrimMaterial, io.papermc.paper.util.Ho public static TrimMaterial objectToBukkit(Object object) { Preconditions.checkArgument(object != null); - return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(object, net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC, Registry.TRIM_MATERIAL); // Paper - switch to Holder + return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(object, net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC, RegistryKey.TRIM_MATERIAL); // Paper - switch to Holder } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java index 0d92f7746..3e3c0d3ba 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.inventory.trim; import com.google.common.base.Preconditions; +import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.util.Holderable; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; @@ -8,18 +9,17 @@ import net.minecraft.network.chat.contents.TranslatableContents; import org.bukkit.NamespacedKey; import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; -import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.inventory.meta.trim.TrimPattern; import org.jetbrains.annotations.NotNull; public class CraftTrimPattern implements TrimPattern, io.papermc.paper.util.Holderable { // Paper - switch to Holder public static TrimPattern minecraftToBukkit(net.minecraft.world.item.equipment.trim.TrimPattern minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_PATTERN, Registry.TRIM_PATTERN); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.TRIM_PATTERN); } public static TrimPattern minecraftHolderToBukkit(Holder minecraft) { - return CraftRegistry.minecraftHolderToBukkit(minecraft, Registry.TRIM_PATTERN); // Paper - switch to Holder + return CraftRegistry.minecraftHolderToBukkit(minecraft, Registries.TRIM_PATTERN); // Paper - switch to Holder } public static net.minecraft.world.item.equipment.trim.TrimPattern bukkitToMinecraft(TrimPattern bukkit) { @@ -42,7 +42,7 @@ public class CraftTrimPattern implements TrimPattern, io.papermc.paper.util.Hold public static TrimPattern objectToBukkit(Object object) { Preconditions.checkArgument(object != null); - return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(object, net.minecraft.world.item.equipment.trim.TrimPattern.CODEC, Registry.TRIM_PATTERN); // Paper - switch to Holder + return io.papermc.paper.util.Holderable.fromBukkitSerializationObject(object, net.minecraft.world.item.equipment.trim.TrimPattern.CODEC, RegistryKey.TRIM_PATTERN); // Paper - switch to Holder } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java index faba7efbd..1376703cd 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/legacy/enums/EnumEvil.java @@ -40,6 +40,7 @@ import org.bukkit.entity.Villager; import org.bukkit.map.MapCursor; import org.bukkit.util.OldEnum; +@Deprecated @NotInBukkit @RequireCompatibility("enum-compatibility-mode") @RequirePluginVersion(maxInclusive = "1.20.6") diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCursor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCursor.java index 9c02115aa..a24cd5850 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCursor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCursor.java @@ -5,7 +5,6 @@ import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.saveddata.maps.MapDecorationType; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.map.MapCursor; @@ -17,7 +16,7 @@ public final class CraftMapCursor { private static int count = 0; public static MapCursor.Type minecraftToBukkit(MapDecorationType minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.MAP_DECORATION_TYPE, Registry.MAP_DECORATION_TYPE); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.MAP_DECORATION_TYPE); } public static MapCursor.Type minecraftHolderToBukkit(Holder minecraft) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java index 0bcb9df11..8d9c141ff 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java @@ -5,7 +5,6 @@ import net.minecraft.core.registries.Registries; import net.minecraft.world.effect.MobEffect; import org.bukkit.Color; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.potion.PotionEffect; @@ -20,7 +19,7 @@ public class CraftPotionEffectType extends PotionEffectType implements Handleabl } public static PotionEffectType minecraftToBukkit(MobEffect minecraft) { - return CraftRegistry.minecraftToBukkit(minecraft, Registries.MOB_EFFECT, Registry.EFFECT); + return CraftRegistry.minecraftToBukkit(minecraft, Registries.MOB_EFFECT); } public static MobEffect bukkitToMinecraft(PotionEffectType bukkit) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java index f1d8ed4a2..24010b74a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionType.java @@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.potion; import com.google.common.base.Preconditions; import com.google.common.base.Suppliers; +import io.papermc.paper.registry.RegistryKey; import java.util.List; import java.util.Locale; import java.util.function.Supplier; @@ -72,7 +73,7 @@ public class CraftPotionType implements PotionType.InternalPotionData { if (key == null) return null; // Paper - Fixup NamespacedKey handling // Now also convert from when keys where saved - return CraftRegistry.get(Registry.POTION, key, ApiVersion.CURRENT); + return CraftRegistry.get(RegistryKey.POTION, key, ApiVersion.CURRENT); } private final NamespacedKey key; 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 327504514..bd8005cd3 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 @@ -12,17 +12,16 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; +import io.papermc.paper.registry.RegistryKey; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Stream; import io.papermc.paper.entity.EntitySerializationFlag; import net.minecraft.SharedConstants; @@ -48,11 +47,9 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.LevelResource; import org.bukkit.Bukkit; -import org.bukkit.FeatureFlag; import org.bukkit.Keyed; import org.bukkit.Material; import org.bukkit.NamespacedKey; -import org.bukkit.Registry; import org.bukkit.UnsafeValues; import org.bukkit.World; import org.bukkit.advancement.Advancement; @@ -66,14 +63,12 @@ import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.CraftBiome; import org.bukkit.craftbukkit.block.data.CraftBlockData; -import org.bukkit.craftbukkit.damage.CraftDamageEffect; import org.bukkit.craftbukkit.damage.CraftDamageSourceBuilder; import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.legacy.CraftLegacy; import org.bukkit.craftbukkit.legacy.FieldRename; import org.bukkit.craftbukkit.potion.CraftPotionType; -import org.bukkit.damage.DamageEffect; import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageType; import org.bukkit.enchantments.Enchantment; @@ -495,7 +490,7 @@ public final class CraftMagicNumbers implements UnsafeValues { } @Override - public B get(Registry registry, NamespacedKey namespacedKey) { + public B get(RegistryKey registry, NamespacedKey namespacedKey) { // We currently do not have any version-dependent remapping, so we can use current version return CraftRegistry.get(registry, namespacedKey, ApiVersion.CURRENT); } diff --git a/paper-server/src/test/java/org/bukkit/registry/PerRegistryTest.java b/paper-server/src/test/java/org/bukkit/registry/PerRegistryTest.java index 319e00051..0ce400166 100644 --- a/paper-server/src/test/java/org/bukkit/registry/PerRegistryTest.java +++ b/paper-server/src/test/java/org/bukkit/registry/PerRegistryTest.java @@ -34,11 +34,11 @@ public class PerRegistryTest { try { Object object = registryField.get(null); // Ignore Bukkit's default SimpleRegistry. It cannot be tested correctly - if (!(object instanceof CraftRegistry registry)) { + if (object instanceof Registry.NotARegistry) { continue; } - data.add(Arguments.of(registry)); + data.add(Arguments.of(object)); } catch (ReflectiveOperationException e) { e.printStackTrace(); } diff --git a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java index 293af3511..49b8fdb1a 100644 --- a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java +++ b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java @@ -1,8 +1,5 @@ package org.bukkit.registry; -import static org.junit.jupiter.api.Assertions.*; -import static org.junit.jupiter.api.Assumptions.*; -import static org.mockito.Mockito.*; import com.google.common.base.Joiner; import io.papermc.paper.registry.RegistryKey; import java.lang.reflect.InvocationTargetException; @@ -13,7 +10,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; import net.minecraft.resources.ResourceKey; -import org.bukkit.Bukkit; import org.bukkit.Keyed; import org.bukkit.Registry; import org.bukkit.craftbukkit.util.Handleable; @@ -25,6 +21,13 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.params.provider.Arguments; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.mockito.Mockito.mock; + @AllFeatures @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class RegistryConversionTest { @@ -260,7 +263,7 @@ public class RegistryConversionTest { Joiner.on('\n').withKeyValueSeparator(" got: ").join(notMatching))); } - static final Set> IGNORE_FOR_DIRECT_HOLDER = Set.of(RegistryKey.TRIM_MATERIAL, RegistryKey.TRIM_PATTERN, RegistryKey.INSTRUMENT, RegistryKey.PAINTING_VARIANT, RegistryKey.BANNER_PATTERN, RegistryKey.SOUND_EVENT); // Paper + static final Set> IGNORE_FOR_DIRECT_HOLDER = Set.of(RegistryKey.TRIM_MATERIAL, RegistryKey.TRIM_PATTERN, RegistryKey.INSTRUMENT, RegistryKey.PAINTING_VARIANT, RegistryKey.BANNER_PATTERN, RegistryKey.SOUND_EVENT, RegistryKey.ENCHANTMENT); // Paper /** * Minecraft registry can return a default key / value From 775002a3579cf34eae1537f2cf7424798b834704 Mon Sep 17 00:00:00 2001 From: David <54660361+NonSwag@users.noreply.github.com> Date: Sat, 11 Jan 2025 20:03:13 +0100 Subject: [PATCH 031/203] [ci skip] Remove nullable from SyncedEntityData#packAll (#11949) --- .../minecraft/network/syncher/SynchedEntityData.java.patch | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch b/paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch index ac8c137be..ea9d95ec4 100644 --- a/paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/syncher/SynchedEntityData.java.patch @@ -23,7 +23,7 @@ public boolean isDirty() { return this.isDirty; } -@@ -169,6 +_,20 @@ +@@ -169,6 +_,19 @@ return new SynchedEntityData(this.entity, this.itemsById); } } @@ -31,9 +31,8 @@ + // Paper start + // We need to pack all as we cannot rely on "non default values" or "dirty" ones. + // Because these values can possibly be desynced on the client. -+ @Nullable + public List> packAll() { -+ final List> list = new ArrayList<>(); ++ final List> list = new ArrayList<>(this.itemsById.length); + for (final DataItem dataItem : this.itemsById) { + list.add(dataItem.value()); + } From c94922514a44d7b15d5fd000b4b82acd259ba751 Mon Sep 17 00:00:00 2001 From: Miles <81843550+Y2Kwastaken@users.noreply.github.com> Date: Sat, 11 Jan 2025 19:21:24 +0000 Subject: [PATCH 032/203] MenuType API addition InventoryView Builders (#11816) --- build-data/paper.at | 1 + .../src/main/java/org/bukkit/Bukkit.java | 17 ++- .../src/main/java/org/bukkit/Server.java | 27 +++-- .../java/org/bukkit/entity/HumanEntity.java | 33 +++++- .../java/org/bukkit/inventory/MenuType.java | 64 +++++----- .../view/builder/InventoryViewBuilder.java | 38 ++++++ .../builder/LocationInventoryViewBuilder.java | 55 +++++++++ .../builder/MerchantInventoryViewBuilder.java | 44 +++++++ .../inventory/view/builder/package-info.java | 9 ++ .../AbstractContainerMenu.java.patch | 3 +- .../world/inventory/ChestMenu.java.patch | 13 ++- .../world/inventory/MerchantMenu.java.patch | 8 ++ .../world/inventory/ShulkerBoxMenu.java.patch | 13 ++- .../org/bukkit/craftbukkit/CraftServer.java | 6 + .../craftbukkit/entity/CraftHumanEntity.java | 8 ++ .../craftbukkit/event/CraftEventFactory.java | 1 + .../craftbukkit/inventory/CraftContainer.java | 2 +- .../craftbukkit/inventory/CraftMenuType.java | 31 +++-- .../inventory/util/CraftMenus.java | 110 +++++++++++++----- .../CraftAbstractInventoryViewBuilder.java | 48 ++++++++ ...tAbstractLocationInventoryViewBuilder.java | 48 ++++++++ ...aftAccessLocationInventoryViewBuilder.java | 45 +++++++ .../CraftBlockEntityInventoryViewBuilder.java | 74 ++++++++++++ .../CraftDoubleChestInventoryViewBuilder.java | 48 ++++++++ .../CraftMerchantInventoryViewBuilder.java | 78 +++++++++++++ .../CraftStandardInventoryViewBuilder.java | 26 +++++ .../inventory/view/builder/package-info.java | 4 + 27 files changed, 759 insertions(+), 95 deletions(-) create mode 100644 paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java create mode 100644 paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java create mode 100644 paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java create mode 100644 paper-api/src/main/java/org/bukkit/inventory/view/builder/package-info.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/package-info.java diff --git a/build-data/paper.at b/build-data/paper.at index 4945a796a..26cdb6eaf 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -725,6 +725,7 @@ public-f net.minecraft.world.item.trading.MerchantOffer rewardExp public-f net.minecraft.world.item.trading.MerchantOffer xp public-f net.minecraft.world.level.LevelSettings hardcore public-f net.minecraft.world.level.LevelSettings levelName +public-f net.minecraft.world.level.block.ChestBlock MENU_PROVIDER_COMBINER public-f net.minecraft.world.level.block.entity.BannerBlockEntity baseColor public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner normalConfig public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner ominousConfig diff --git a/paper-api/src/main/java/org/bukkit/Bukkit.java b/paper-api/src/main/java/org/bukkit/Bukkit.java index 9eecd3a68..9196b1e62 100644 --- a/paper-api/src/main/java/org/bukkit/Bukkit.java +++ b/paper-api/src/main/java/org/bukkit/Bukkit.java @@ -40,6 +40,7 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemCraftResult; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MenuType; import org.bukkit.inventory.Merchant; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.meta.ItemMeta; @@ -1925,7 +1926,10 @@ public final class Bukkit { * @param title the title of the corresponding merchant inventory, displayed * when the merchant inventory is viewed * @return a new merchant + * @deprecated The title parameter is no-longer needed when used with + * {@link MenuType#MERCHANT} and {@link MenuType.Typed#builder()}. */ + @Deprecated(since = "1.21.4") public static @NotNull Merchant createMerchant(net.kyori.adventure.text.@Nullable Component title) { return server.createMerchant(title); } @@ -1936,7 +1940,8 @@ public final class Bukkit { * @param title the title of the corresponding merchant inventory, displayed * when the merchant inventory is viewed * @return a new merchant - * @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)} + * @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)}. The title parameter is + * no-longer needed when used with {@link MenuType#MERCHANT} and {@link MenuType.Typed#builder()} */ @NotNull @Deprecated // Paper @@ -1944,6 +1949,16 @@ public final class Bukkit { return server.createMerchant(title); } + /** + * Creates an empty merchant. + * + * @return a new merchant + */ + @NotNull + public static Merchant createMerchant() { + return server.createMerchant(); + } + /** * Gets the amount of consecutive neighbor updates before skipping * additional ones. diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index 041ebeb28..11923ef0e 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -43,6 +43,7 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemCraftResult; import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MenuType; import org.bukkit.inventory.Merchant; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.meta.ItemMeta; @@ -1565,11 +1566,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi *
* {@link InventoryType#WORKBENCH} will not process crafting recipes if * created with this method. Use - * {@link Player#openWorkbench(Location, boolean)} instead. + * {@link MenuType#CRAFTING} instead. *
* {@link InventoryType#ENCHANTING} will not process {@link ItemStack}s * for possible enchanting results. Use - * {@link Player#openEnchanting(Location, boolean)} instead. + * {@link MenuType#ENCHANTMENT} instead. * * @param owner the holder of the inventory, or null to indicate no holder * @param type the type of inventory to create @@ -1592,11 +1593,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi *
* {@link InventoryType#WORKBENCH} will not process crafting recipes if * created with this method. Use - * {@link Player#openWorkbench(Location, boolean)} instead. + * {@link MenuType#CRAFTING} instead. *
* {@link InventoryType#ENCHANTING} will not process {@link ItemStack}s * for possible enchanting results. Use - * {@link Player#openEnchanting(Location, boolean)} instead. + * {@link MenuType#ENCHANTMENT} instead. * * @param owner The holder of the inventory; can be null if there's no holder. * @param type The type of inventory to create. @@ -1620,11 +1621,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi *
* {@link InventoryType#WORKBENCH} will not process crafting recipes if * created with this method. Use - * {@link Player#openWorkbench(Location, boolean)} instead. + * {@link MenuType#CRAFTING} instead. *
* {@link InventoryType#ENCHANTING} will not process {@link ItemStack}s * for possible enchanting results. Use - * {@link Player#openEnchanting(Location, boolean)} instead. + * {@link MenuType#ENCHANTMENT} instead. * * @param owner The holder of the inventory; can be null if there's no holder. * @param type The type of inventory to create. @@ -1691,7 +1692,10 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @param title the title of the corresponding merchant inventory, displayed * when the merchant inventory is viewed * @return a new merchant + * @deprecated The title parameter is no-longer needed when used with + * {@link MenuType#MERCHANT} and {@link MenuType.Typed#builder()}. */ + @Deprecated(since = "1.21.4") @NotNull Merchant createMerchant(net.kyori.adventure.text.@Nullable Component title); // Paper start /** @@ -1700,7 +1704,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @param title the title of the corresponding merchant inventory, displayed * when the merchant inventory is viewed * @return a new merchant - * @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)} + * @deprecated in favour of {@link #createMerchant(net.kyori.adventure.text.Component)}, The title parameter is + * no-longer needed when used with {@link MenuType#MERCHANT} and {@link MenuType.Typed#builder()}. */ @NotNull @Deprecated // Paper @@ -1715,6 +1720,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ int getMaxChainedNeighborUpdates(); + /** + * Creates an empty merchant. + * + * @return a new merchant + */ + @NotNull + Merchant createMerchant(); + /** * Gets user-specified limit for number of monsters that can spawn in a * chunk. 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 6303c68b2..f04a6bf9e 100644 --- a/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java @@ -13,6 +13,7 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.MainHand; +import org.bukkit.inventory.MenuType; import org.bukkit.inventory.Merchant; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.FireworkMeta; @@ -126,7 +127,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#CRAFTING} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openWorkbench(@Nullable Location location, boolean force); @@ -140,7 +144,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * location, no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#ENCHANTMENT} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openEnchanting(@Nullable Location location, boolean force); @@ -166,8 +173,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param trader The merchant to trade with. Cannot be null. * @param force whether to force the trade even if another player is trading * @return The newly opened inventory view, or null if it could not be - * opened. + * @deprecated This method can be replaced by using {@link MenuType#MERCHANT} + * in conjunction with {@link #openInventory(InventoryView)}. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openMerchant(@NotNull Villager trader, boolean force); @@ -180,8 +189,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param merchant The merchant to trade with. Cannot be null. * @param force whether to force the trade even if another player is trading * @return The newly opened inventory view, or null if it could not be - * opened. + * @deprecated This method can be replaced by using {@link MenuType#MERCHANT} + * in conjunction with {@link #openInventory(InventoryView)}. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openMerchant(@NotNull Merchant merchant, boolean force); @@ -196,7 +207,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#ANVIL} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openAnvil(@Nullable Location location, boolean force); @@ -210,7 +224,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#CARTOGRAPHY_TABLE} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openCartographyTable(@Nullable Location location, boolean force); @@ -224,7 +241,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#GRINDSTONE} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openGrindstone(@Nullable Location location, boolean force); @@ -238,7 +258,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#LOOM} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openLoom(@Nullable Location location, boolean force); @@ -252,7 +275,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#SMITHING} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openSmithingTable(@Nullable Location location, boolean force); @@ -266,7 +292,10 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * no inventory will be opened and null will be returned. * @return The newly opened inventory view, or null if it could not be * opened. + * @deprecated This method should be replaced by {@link MenuType#STONECUTTER} + * see {@link MenuType.Typed#builder()} and its options for more information. */ + @Deprecated(since = "1.21.4") @Nullable public InventoryView openStonecutter(@Nullable Location location, boolean force); // Paper end diff --git a/paper-api/src/main/java/org/bukkit/inventory/MenuType.java b/paper-api/src/main/java/org/bukkit/inventory/MenuType.java index 529143c90..2442361ce 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/MenuType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/MenuType.java @@ -14,6 +14,9 @@ import org.bukkit.inventory.view.LecternView; import org.bukkit.inventory.view.LoomView; import org.bukkit.inventory.view.MerchantView; import org.bukkit.inventory.view.StonecutterView; +import org.bukkit.inventory.view.builder.InventoryViewBuilder; +import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; +import org.bukkit.inventory.view.builder.MerchantInventoryViewBuilder; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -27,104 +30,104 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe /** * A MenuType which represents a chest with 1 row. */ - MenuType.Typed GENERIC_9X1 = get("generic_9x1"); + MenuType.Typed> GENERIC_9X1 = get("generic_9x1"); /** * A MenuType which represents a chest with 2 rows. */ - MenuType.Typed GENERIC_9X2 = get("generic_9x2"); + MenuType.Typed> GENERIC_9X2 = get("generic_9x2"); /** * A MenuType which represents a chest with 3 rows. */ - MenuType.Typed GENERIC_9X3 = get("generic_9x3"); + MenuType.Typed> GENERIC_9X3 = get("generic_9x3"); /** * A MenuType which represents a chest with 4 rows. */ - MenuType.Typed GENERIC_9X4 = get("generic_9x4"); + MenuType.Typed> GENERIC_9X4 = get("generic_9x4"); /** * A MenuType which represents a chest with 5 rows. */ - MenuType.Typed GENERIC_9X5 = get("generic_9x5"); + MenuType.Typed> GENERIC_9X5 = get("generic_9x5"); /** * A MenuType which represents a chest with 6 rows. */ - MenuType.Typed GENERIC_9X6 = get("generic_9x6"); + MenuType.Typed> GENERIC_9X6 = get("generic_9x6"); /** * A MenuType which represents a dispenser/dropper like menu with 3 columns * and 3 rows. */ - MenuType.Typed GENERIC_3X3 = get("generic_3x3"); + MenuType.Typed> GENERIC_3X3 = get("generic_3x3"); /** * A MenuType which represents a crafter */ - MenuType.Typed CRAFTER_3X3 = get("crafter_3x3"); + MenuType.Typed> CRAFTER_3X3 = get("crafter_3x3"); /** * A MenuType which represents an anvil. */ - MenuType.Typed ANVIL = get("anvil"); + MenuType.Typed> ANVIL = get("anvil"); /** * A MenuType which represents a beacon. */ - MenuType.Typed BEACON = get("beacon"); + MenuType.Typed> BEACON = get("beacon"); /** * A MenuType which represents a blast furnace. */ - MenuType.Typed BLAST_FURNACE = get("blast_furnace"); + MenuType.Typed> BLAST_FURNACE = get("blast_furnace"); /** * A MenuType which represents a brewing stand. */ - MenuType.Typed BREWING_STAND = get("brewing_stand"); + MenuType.Typed> BREWING_STAND = get("brewing_stand"); /** * A MenuType which represents a crafting table. */ - MenuType.Typed CRAFTING = get("crafting"); + MenuType.Typed> CRAFTING = get("crafting"); /** * A MenuType which represents an enchantment table. */ - MenuType.Typed ENCHANTMENT = get("enchantment"); + MenuType.Typed> ENCHANTMENT = get("enchantment"); /** * A MenuType which represents a furnace. */ - MenuType.Typed FURNACE = get("furnace"); + MenuType.Typed> FURNACE = get("furnace"); /** * A MenuType which represents a grindstone. */ - MenuType.Typed GRINDSTONE = get("grindstone"); + MenuType.Typed> GRINDSTONE = get("grindstone"); /** * A MenuType which represents a hopper. */ - MenuType.Typed HOPPER = get("hopper"); + MenuType.Typed> HOPPER = get("hopper"); /** * A MenuType which represents a lectern, a book like view. */ - MenuType.Typed LECTERN = get("lectern"); + MenuType.Typed> LECTERN = get("lectern"); /** * A MenuType which represents a loom. */ - MenuType.Typed LOOM = get("loom"); + MenuType.Typed> LOOM = get("loom"); /** * A MenuType which represents a merchant. */ - MenuType.Typed MERCHANT = get("merchant"); + MenuType.Typed> MERCHANT = get("merchant"); /** * A MenuType which represents a shulker box. */ - MenuType.Typed SHULKER_BOX = get("shulker_box"); + MenuType.Typed> SHULKER_BOX = get("shulker_box"); /** * A MenuType which represents a stonecutter. */ - MenuType.Typed SMITHING = get("smithing"); + MenuType.Typed> SMITHING = get("smithing"); /** * A MenuType which represents a smoker. */ - MenuType.Typed SMOKER = get("smoker"); + MenuType.Typed> SMOKER = get("smoker"); /** * A MenuType which represents a cartography table. */ - MenuType.Typed CARTOGRAPHY_TABLE = get("cartography_table"); + MenuType.Typed> CARTOGRAPHY_TABLE = get("cartography_table"); /** * A MenuType which represents a stonecutter. */ - MenuType.Typed STONECUTTER = get("stonecutter"); + MenuType.Typed> STONECUTTER = get("stonecutter"); /** * Typed represents a subtype of {@link MenuType}s that have a known @@ -133,7 +136,7 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * @param the generic type of {@link InventoryView} that represents the * view type. */ - interface Typed extends MenuType { + interface Typed> extends MenuType { /** * Creates a view of the specified menu type. @@ -166,6 +169,9 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe @NotNull V create(@NotNull HumanEntity player, @NotNull net.kyori.adventure.text.Component title); // Paper end - adventure + + @NotNull + B builder(); } // Paper start - adventure @@ -191,7 +197,7 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * @return the typed MenuType. */ @NotNull - MenuType.Typed typed(); + MenuType.Typed> typed(); /** * Yields this MenuType as a typed version of itself with a specific @@ -201,12 +207,14 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * {@link InventoryView} with. * @param the generic type of the InventoryView to get this MenuType * with + * @param the generic type of the InventoryViewBuilder to get this + * MenuType with * @return the typed MenuType * @throws IllegalArgumentException if the provided viewClass cannot be * typed to this MenuType */ @NotNull - MenuType.Typed typed(@NotNull final Class viewClass) throws IllegalArgumentException; + > MenuType.Typed typed(@NotNull final Class viewClass) throws IllegalArgumentException; /** * Gets the {@link InventoryView} class of this MenuType. diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java new file mode 100644 index 000000000..9f0752228 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java @@ -0,0 +1,38 @@ +package org.bukkit.inventory.view.builder; + +import net.kyori.adventure.text.Component; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryView; +import org.jetbrains.annotations.ApiStatus; + +/** + * Generic Builder for InventoryView's with no special attributes or parameters + * + * @param the type of InventoryView created from this builder + */ +@ApiStatus.Experimental +public interface InventoryViewBuilder { + + /** + * Makes a copy of this builder + * + * @return a copy of this builder + */ + InventoryViewBuilder copy(); + + /** + * Sets the title of the builder + * + * @param title the title + * @return this builder + */ + InventoryViewBuilder title(final Component title); + + /** + * Builds this builder into a InventoryView + * + * @param player the player to assign to the view + * @return the created InventoryView + */ + V build(final HumanEntity player); +} diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java new file mode 100644 index 000000000..9666aa356 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java @@ -0,0 +1,55 @@ +package org.bukkit.inventory.view.builder; + +import net.kyori.adventure.text.Component; +import org.bukkit.Location; +import org.bukkit.inventory.InventoryView; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * An InventoryViewBuilder that can be bound by location within the world + * + * @param the type of InventoryView created from this builder + */ +@ApiStatus.Experimental +public interface LocationInventoryViewBuilder extends InventoryViewBuilder { + + @Override + LocationInventoryViewBuilder copy(); + + @Override + LocationInventoryViewBuilder title(final @NotNull Component title); + + /** + * Determines whether or not the server should check if the player can reach + * the location. + *

+ * Not providing a location but setting checkReachable to true will + * automatically close the view when opened. + *

+ * If checkReachable is set to false and a location is set on the builder if + * the target block exists and this builder is the correct menu for that + * block, e.g. MenuType.GENERIC_9X3 builder and target block set to chest, + * if that block is destroyed the view would persist. + * + * @param checkReachable whether or not to check if the view is "reachable" + * @return this builder + */ + LocationInventoryViewBuilder checkReachable(final boolean checkReachable); + + /** + * Binds a location to this builder. + *

+ * By binding a location in an unloaded chunk to this builder it is likely + * that the given chunk the location is will load. That means that when, + * building this view it may come with the costs associated with chunk + * loading. + *

+ * Providing a location of a tile entity with a non matching menu comes with + * extra costs associated with ensuring that the correct view is created. + * + * @param location the location to bind to this view + * @return this builder + */ + LocationInventoryViewBuilder location(final Location location); +} diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java new file mode 100644 index 000000000..76aecb54a --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java @@ -0,0 +1,44 @@ +package org.bukkit.inventory.view.builder; + +import net.kyori.adventure.text.Component; +import org.bukkit.Server; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.Merchant; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * An InventoryViewBuilder for creating merchant views + * + * @param the type of InventoryView created by this builder + */ +@ApiStatus.Experimental +public interface MerchantInventoryViewBuilder extends InventoryViewBuilder { + + @Override + MerchantInventoryViewBuilder copy(); + + @Override + MerchantInventoryViewBuilder title(final @NotNull Component title); + + /** + * Adds a merchant to this builder + * + * @param merchant the merchant + * @return this builder + */ + MerchantInventoryViewBuilder merchant(final Merchant merchant); + + /** + * Determines whether or not the server should check if the player can reach + * the location. + *

+ * Given checkReachable is provided and a virtual merchant is provided to + * the builder from {@link Server#createMerchant(net.kyori.adventure.text.Component)} this method will + * have no effect on the actual menu status. + * + * @param checkReachable whether or not to check if the view is "reachable" + * @return this builder + */ + MerchantInventoryViewBuilder checkReachable(final boolean checkReachable); +} diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/package-info.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/package-info.java new file mode 100644 index 000000000..b1e4203da --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/package-info.java @@ -0,0 +1,9 @@ +/** + * A Package that contains builders for building InventoryViews. + */ +@NullMarked +@ApiStatus.Experimental +package org.bukkit.inventory.view.builder; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch index e33c611fe..6b7e7d70c 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch @@ -9,7 +9,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.Mth; import net.minecraft.world.Container; -@@ -63,6 +_,31 @@ +@@ -63,6 +_,32 @@ @Nullable private ContainerSynchronizer synchronizer; private boolean suppressRemoteUpdates; @@ -37,6 +37,7 @@ + com.google.common.base.Preconditions.checkState(this.title == null, "Title already set"); + this.title = title; + } ++ public void startOpen() {} + // CraftBukkit end protected AbstractContainerMenu(@Nullable MenuType menuType, int containerId) { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ChestMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ChestMenu.java.patch index c86ead27c..1be2d1bc4 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/ChestMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/ChestMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/ChestMenu.java +++ b/net/minecraft/world/inventory/ChestMenu.java -@@ -9,6 +_,29 @@ +@@ -9,6 +_,34 @@ public class ChestMenu extends AbstractContainerMenu { private final Container container; private final int containerRows; @@ -26,14 +26,21 @@ + this.bukkitEntity = new org.bukkit.craftbukkit.inventory.CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return this.bukkitEntity; + } ++ ++ @Override ++ public void startOpen() { ++ this.container.startOpen(this.player.player); ++ } + // CraftBukkit end private ChestMenu(MenuType type, int containerId, Inventory playerInventory, int rows) { this(type, containerId, playerInventory, new SimpleContainer(9 * rows), rows); -@@ -52,6 +_,9 @@ +@@ -51,7 +_,10 @@ + checkContainerSize(container, rows * 9); this.container = container; this.containerRows = rows; - container.startOpen(playerInventory.player); +- container.startOpen(playerInventory.player); ++ // container.startOpen(playerInventory.player); // Paper - don't startOpen until menu actually opens + // CraftBukkit start - Save player + this.player = playerInventory; + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/MerchantMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/MerchantMenu.java.patch index d3c402326..f1c3c78a5 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/MerchantMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/MerchantMenu.java.patch @@ -27,6 +27,14 @@ this.addStandardInventorySlots(playerInventory, 108, 84); } +@@ -61,6 +_,7 @@ + + @Override + public boolean stillValid(Player player) { ++ if (!checkReachable) return true; // Paper - checkReachable + return this.trader.stillValid(player); + } + @@ -105,12 +_,12 @@ ItemStack item = slot.getItem(); itemStack = item.copy(); diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ShulkerBoxMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ShulkerBoxMenu.java.patch index a65b4c24d..590e2788d 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/ShulkerBoxMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/ShulkerBoxMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/ShulkerBoxMenu.java +++ b/net/minecraft/world/inventory/ShulkerBoxMenu.java -@@ -9,6 +_,20 @@ +@@ -9,6 +_,25 @@ public class ShulkerBoxMenu extends AbstractContainerMenu { private static final int CONTAINER_SIZE = 27; private final Container container; @@ -17,18 +17,25 @@ + this.bukkitEntity = new org.bukkit.craftbukkit.inventory.CraftInventoryView(this.player.player.getBukkitEntity(), new org.bukkit.craftbukkit.inventory.CraftInventory(this.container), this); + return this.bukkitEntity; + } ++ ++ @Override ++ public void startOpen() { ++ container.startOpen(player.player); ++ } + // CraftBukkit end public ShulkerBoxMenu(int containerId, Inventory playerInventory) { this(containerId, playerInventory, new SimpleContainer(27)); -@@ -18,6 +_,7 @@ +@@ -18,7 +_,8 @@ super(MenuType.SHULKER_BOX, containerId); checkContainerSize(container, 27); this.container = container; +- container.startOpen(playerInventory.player); + this.player = playerInventory; // CraftBukkit - save player - container.startOpen(playerInventory.player); ++ // container.startOpen(playerInventory.player); // Paper - don't startOpen until menu actually opens int i = 3; int i1 = 9; + @@ -33,6 +_,7 @@ @Override 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 fda9daa63..d2de78996 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -258,6 +258,7 @@ import org.bukkit.scoreboard.Criteria; import org.bukkit.structure.StructureManager; import org.bukkit.util.StringUtil; import org.bukkit.util.permissions.DefaultPermissions; +import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; @@ -2485,6 +2486,11 @@ public final class CraftServer implements Server { return new CraftMerchantCustom(title == null ? InventoryType.MERCHANT.getDefaultTitle() : title); } + @Override + public @NotNull Merchant createMerchant() { + return new CraftMerchantCustom(net.kyori.adventure.text.Component.empty()); + } + @Override public int getMaxChainedNeighborUpdates() { return this.getServer().getMaxChainedNeighborUpdates(); 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 a1f42f860..cafd8c534 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 @@ -25,6 +25,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FireworkRocketEntity; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.MerchantMenu; import net.minecraft.world.item.ItemCooldowns; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.item.crafting.RecipeManager; @@ -50,6 +51,8 @@ import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftMerchantCustom; import org.bukkit.craftbukkit.inventory.CraftRecipe; +import org.bukkit.craftbukkit.inventory.util.CraftMenus; +import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.entity.Firework; import org.bukkit.entity.HumanEntity; @@ -467,6 +470,11 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { // Now open the window MenuType windowType = CraftContainer.getNotchInventoryType(inventory.getTopInventory()); + // we can open these now, delegate for now + if (windowType == MenuType.MERCHANT) { + CraftMenus.openMerchantMenu(player, (MerchantMenu) container); + return; + } //String title = inventory.getTitle(); // Paper - comment net.kyori.adventure.text.Component adventure$title = inventory.title(); // Paper 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 e37aaf77f..d7a52220e 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 @@ -1430,6 +1430,7 @@ public class CraftEventFactory { } public static com.mojang.datafixers.util.Pair callInventoryOpenEventWithTitle(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) { // Paper end - Add titleOverride to InventoryOpenEvent + container.startOpen(); // delegate start open logic to before InventoryOpenEvent is fired if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason } 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 6d3f9d5da..1ce328bed 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 @@ -132,7 +132,7 @@ public class CraftContainer extends AbstractContainerMenu { if (menu == null) { return net.minecraft.world.inventory.MenuType.GENERIC_9x3; } else { - return ((CraftMenuType) menu).getHandle(); + return ((CraftMenuType) menu).getHandle(); } } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java index e4d81ef26..4c6cf43ce 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java @@ -15,12 +15,14 @@ import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.MenuType; +import org.bukkit.inventory.view.builder.InventoryViewBuilder; +import org.jetbrains.annotations.NotNull; -public class CraftMenuType implements MenuType.Typed, Handleable>, io.papermc.paper.world.flag.PaperFeatureDependent { // Paper - make FeatureDependant +public class CraftMenuType> implements MenuType.Typed, Handleable>, io.papermc.paper.world.flag.PaperFeatureDependent { // Paper - make FeatureDependant private final NamespacedKey key; private final net.minecraft.world.inventory.MenuType handle; - private final Supplier> typeData; + private final Supplier> typeData; public CraftMenuType(NamespacedKey key, net.minecraft.world.inventory.MenuType handle) { this.key = key; @@ -36,33 +38,28 @@ public class CraftMenuType implements MenuType.Typed @Override public V create(final HumanEntity player, final String title) { // Paper start - adventure - return create(player, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(title)); + return builder().title(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(title)).build(player); } @Override public V create(final HumanEntity player, final net.kyori.adventure.text.Component title) { // Paper end - adventure - Preconditions.checkArgument(player != null, "The given player must not be null"); - Preconditions.checkArgument(title != null, "The given title must not be null"); - Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity"); - final CraftHumanEntity craftHuman = (CraftHumanEntity) player; - Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer"); - final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle(); - - final AbstractContainerMenu container = this.typeData.get().menuBuilder().build(serverPlayer, this.handle); - container.setTitle(io.papermc.paper.adventure.PaperAdventure.asVanilla(title)); // Paper - adventure - container.checkReachable = false; - return (V) container.getBukkitView(); + return builder().title(title).build(player); } @Override - public Typed typed() { + public B builder() { + return typeData.get().viewBuilder().get(); + } + + @Override + public Typed> typed() { return this.typed(InventoryView.class); } @Override - public Typed typed(Class clazz) { + public > Typed typed(Class clazz) { if (clazz.isAssignableFrom(this.typeData.get().viewClass())) { - return (Typed) this; + return (Typed) this; } throw new IllegalArgumentException("Cannot type InventoryView " + this.key.toString() + " to InventoryView type " + clazz.getSimpleName()); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftMenus.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftMenus.java index 66e93f844..84c35792c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftMenus.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftMenus.java @@ -1,16 +1,18 @@ package org.bukkit.craftbukkit.inventory.util; -import static org.bukkit.craftbukkit.inventory.util.CraftMenuBuilder.*; - -import net.minecraft.network.chat.Component; -import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.npc.Villager; import net.minecraft.world.inventory.AnvilMenu; import net.minecraft.world.inventory.CartographyTableMenu; import net.minecraft.world.inventory.CraftingMenu; import net.minecraft.world.inventory.EnchantmentMenu; import net.minecraft.world.inventory.GrindstoneMenu; +import net.minecraft.world.inventory.MerchantMenu; import net.minecraft.world.inventory.SmithingMenu; import net.minecraft.world.inventory.StonecutterMenu; +import net.minecraft.world.item.trading.Merchant; +import net.minecraft.world.item.trading.MerchantOffers; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BlastFurnaceBlockEntity; @@ -20,8 +22,15 @@ import net.minecraft.world.level.block.entity.DispenserBlockEntity; import net.minecraft.world.level.block.entity.FurnaceBlockEntity; import net.minecraft.world.level.block.entity.HopperBlockEntity; import net.minecraft.world.level.block.entity.LecternBlockEntity; +import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; import net.minecraft.world.level.block.entity.SmokerBlockEntity; import org.bukkit.craftbukkit.inventory.CraftMenuType; +import org.bukkit.craftbukkit.inventory.CraftMerchant; +import org.bukkit.craftbukkit.inventory.view.builder.CraftAccessLocationInventoryViewBuilder; +import org.bukkit.craftbukkit.inventory.view.builder.CraftBlockEntityInventoryViewBuilder; +import org.bukkit.craftbukkit.inventory.view.builder.CraftDoubleChestInventoryViewBuilder; +import org.bukkit.craftbukkit.inventory.view.builder.CraftMerchantInventoryViewBuilder; +import org.bukkit.craftbukkit.inventory.view.builder.CraftStandardInventoryViewBuilder; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.MenuType; import org.bukkit.inventory.view.AnvilView; @@ -34,83 +43,120 @@ import org.bukkit.inventory.view.LecternView; import org.bukkit.inventory.view.LoomView; import org.bukkit.inventory.view.MerchantView; import org.bukkit.inventory.view.StonecutterView; +import org.bukkit.inventory.view.builder.InventoryViewBuilder; +import org.jspecify.annotations.NullMarked; +import java.util.function.Supplier; + +@NullMarked public final class CraftMenus { - public record MenuTypeData(Class viewClass, CraftMenuBuilder menuBuilder) { + public record MenuTypeData>(Class viewClass, Supplier viewBuilder) { } - private static final CraftMenuBuilder STANDARD = (player, menuType) -> menuType.create(player.nextContainerCounter(), player.getInventory()); + // This is a temporary measure that will likely be removed with the rewrite of HumanEntity#open[] methods + public static void openMerchantMenu(final ServerPlayer player, final MerchantMenu merchant) { + final Merchant minecraftMerchant = ((CraftMerchant) merchant.getBukkitView().getMerchant()).getMerchant(); + int level = 1; + if (minecraftMerchant instanceof final Villager villager) { + level = villager.getVillagerData().getLevel(); + } - public static MenuTypeData getMenuTypeData(CraftMenuType menuType) { + if (minecraftMerchant.getTradingPlayer() != null) { // merchant's can only have one trader + minecraftMerchant.getTradingPlayer().closeContainer(); + } + + minecraftMerchant.setTradingPlayer(player); + + player.connection.send(new ClientboundOpenScreenPacket(merchant.containerId, net.minecraft.world.inventory.MenuType.MERCHANT, merchant.getTitle())); + player.containerMenu = merchant; + player.initMenu(merchant); + // Copy IMerchant#openTradingScreen + MerchantOffers merchantrecipelist = minecraftMerchant.getOffers(); + + if (!merchantrecipelist.isEmpty()) { + player.sendMerchantOffers(merchant.containerId, merchantrecipelist, level, minecraftMerchant.getVillagerXp(), minecraftMerchant.showProgressBar(), minecraftMerchant.canRestock()); + } + // End Copy IMerchant#openTradingScreen + } + + public static > MenuTypeData getMenuTypeData(final CraftMenuType menuType) { + final net.minecraft.world.inventory.MenuType handle = menuType.getHandle(); + // this sucks horribly but it should work for now + if (menuType == MenuType.GENERIC_9X6) { + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftDoubleChestInventoryViewBuilder<>(handle))); + } + if (menuType == MenuType.GENERIC_9X3) { + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, null))); + } // this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9 // this needs to be removed when inventory creation is overhauled if (menuType == MenuType.GENERIC_3X3) { - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, tileEntity(DispenserBlockEntity::new, Blocks.DISPENSER))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.DISPENSER, DispenserBlockEntity::new))); } if (menuType == MenuType.CRAFTER_3X3) { - return CraftMenus.asType(new MenuTypeData<>(CrafterView.class, tileEntity(CrafterBlockEntity::new, Blocks.CRAFTER))); + return asType(new MenuTypeData<>(CrafterView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CRAFTER, CrafterBlockEntity::new))); } if (menuType == MenuType.ANVIL) { - return CraftMenus.asType(new MenuTypeData<>(AnvilView.class, worldAccess(AnvilMenu::new))); + return asType(new MenuTypeData<>(AnvilView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, AnvilMenu::new))); } if (menuType == MenuType.BEACON) { - return CraftMenus.asType(new MenuTypeData<>(BeaconView.class, tileEntity(BeaconBlockEntity::new, Blocks.BEACON))); + return asType(new MenuTypeData<>(BeaconView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BEACON, BeaconBlockEntity::new))); } if (menuType == MenuType.BLAST_FURNACE) { - return CraftMenus.asType(new MenuTypeData<>(FurnaceView.class, tileEntity(BlastFurnaceBlockEntity::new, Blocks.BLAST_FURNACE))); + return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BLAST_FURNACE, BlastFurnaceBlockEntity::new))); } if (menuType == MenuType.BREWING_STAND) { - return CraftMenus.asType(new MenuTypeData<>(BrewingStandView.class, tileEntity(BrewingStandBlockEntity::new, Blocks.BREWING_STAND))); + return asType(new MenuTypeData<>(BrewingStandView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BREWING_STAND, BrewingStandBlockEntity::new))); } if (menuType == MenuType.CRAFTING) { - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, worldAccess(CraftingMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, CraftingMenu::new))); } if (menuType == MenuType.ENCHANTMENT) { - return CraftMenus.asType(new MenuTypeData<>(EnchantmentView.class, (player, type) -> { - return new SimpleMenuProvider((syncId, inventory, human) -> { - return worldAccess(EnchantmentMenu::new).build(player, type); - }, Component.empty()).createMenu(player.nextContainerCounter(), player.getInventory(), player); - })); + return asType(new MenuTypeData<>(EnchantmentView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, EnchantmentMenu::new))); } if (menuType == MenuType.FURNACE) { - return CraftMenus.asType(new MenuTypeData<>(FurnaceView.class, tileEntity(FurnaceBlockEntity::new, Blocks.FURNACE))); + return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.FURNACE, FurnaceBlockEntity::new))); } if (menuType == MenuType.GRINDSTONE) { - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, worldAccess(GrindstoneMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, GrindstoneMenu::new))); } // We really don't need to be creating a tile entity for hopper but currently InventoryType doesn't have capacity // to understand otherwise if (menuType == MenuType.HOPPER) { - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, tileEntity(HopperBlockEntity::new, Blocks.HOPPER))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.HOPPER, HopperBlockEntity::new))); } // We also don't need to create a tile entity for lectern, but again InventoryType isn't smart enough to know any better if (menuType == MenuType.LECTERN) { - return CraftMenus.asType(new MenuTypeData<>(LecternView.class, tileEntity(LecternBlockEntity::new, Blocks.LECTERN))); + return asType(new MenuTypeData<>(LecternView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.LECTERN, LecternBlockEntity::new))); } if (menuType == MenuType.LOOM) { - return CraftMenus.asType(new MenuTypeData<>(LoomView.class, CraftMenus.STANDARD)); + return asType(new MenuTypeData<>(LoomView.class, () -> new CraftStandardInventoryViewBuilder<>(handle))); } if (menuType == MenuType.MERCHANT) { - return CraftMenus.asType(new MenuTypeData<>(MerchantView.class, CraftMenus.STANDARD)); + return asType(new MenuTypeData<>(MerchantView.class, () -> new CraftMerchantInventoryViewBuilder<>(handle))); + } + if (menuType == MenuType.SHULKER_BOX) { + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SHULKER_BOX, ShulkerBoxBlockEntity::new))); } if (menuType == MenuType.SMITHING) { - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, worldAccess(SmithingMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, SmithingMenu::new))); } if (menuType == MenuType.SMOKER) { - return CraftMenus.asType(new MenuTypeData<>(FurnaceView.class, tileEntity(SmokerBlockEntity::new, Blocks.SMOKER))); + return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SMOKER, SmokerBlockEntity::new))); } if (menuType == MenuType.CARTOGRAPHY_TABLE) { - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, worldAccess(CartographyTableMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, CartographyTableMenu::new))); } if (menuType == MenuType.STONECUTTER) { - return CraftMenus.asType(new MenuTypeData<>(StonecutterView.class, worldAccess(StonecutterMenu::new))); + return asType(new MenuTypeData<>(StonecutterView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, StonecutterMenu::new))); } - return CraftMenus.asType(new MenuTypeData<>(InventoryView.class, CraftMenus.STANDARD)); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftStandardInventoryViewBuilder<>(handle))); } - private static MenuTypeData asType(MenuTypeData data) { - return (MenuTypeData) data; + @SuppressWarnings("unchecked") + private static > MenuTypeData asType(final MenuTypeData data) { + return (MenuTypeData) data; } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java new file mode 100644 index 000000000..185ad0fc1 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import com.google.common.base.Preconditions; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.view.builder.InventoryViewBuilder; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +public abstract class CraftAbstractInventoryViewBuilder implements InventoryViewBuilder { + + protected final MenuType handle; + + protected boolean checkReachable = false; + protected @MonotonicNonNull Component title = null; + + public CraftAbstractInventoryViewBuilder(final MenuType handle) { + this.handle = handle; + } + + @Override + public InventoryViewBuilder title(final Component title) { + this.title = title; + return this; + } + + @SuppressWarnings("unchecked") + @Override + public V build(final HumanEntity player) { + Preconditions.checkArgument(player != null, "The given player must not be null"); + Preconditions.checkArgument(this.title != null, "The given title must not be null"); + Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity"); + final CraftHumanEntity craftHuman = (CraftHumanEntity) player; + Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer"); + final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle(); + final AbstractContainerMenu container = buildContainer(serverPlayer); + container.checkReachable = this.checkReachable; + container.setTitle(PaperAdventure.asVanilla(this.title)); + return (V) container.getBukkitView(); + } + + protected abstract AbstractContainerMenu buildContainer(ServerPlayer player); +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java new file mode 100644 index 000000000..7a894ca07 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import com.google.common.base.Preconditions; +import net.kyori.adventure.text.Component; +import net.minecraft.core.BlockPos; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.Level; +import org.bukkit.Location; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.CraftLocation; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; +import org.jspecify.annotations.Nullable; + +public abstract class CraftAbstractLocationInventoryViewBuilder extends CraftAbstractInventoryViewBuilder implements LocationInventoryViewBuilder { + + protected @Nullable Level world; + protected @Nullable BlockPos position; + + public CraftAbstractLocationInventoryViewBuilder(final MenuType handle) { + super(handle); + } + + @Override + public LocationInventoryViewBuilder title(final Component title) { + return (LocationInventoryViewBuilder) super.title(title); + } + + @Override + public LocationInventoryViewBuilder copy() { + throw new UnsupportedOperationException("copy is not implemented on CraftAbstractLocationInventoryViewBuilder"); + } + + @Override + public LocationInventoryViewBuilder checkReachable(final boolean checkReachable) { + super.checkReachable = checkReachable; + return this; + } + + @Override + public LocationInventoryViewBuilder location(final Location location) { + Preconditions.checkArgument(location != null, "The provided location must not be null"); + Preconditions.checkArgument(location.getWorld() != null, "The provided location must be associated with a world"); + this.world = ((CraftWorld) location.getWorld()).getHandle(); + this.position = CraftLocation.toBlockPosition(location); + return this; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java new file mode 100644 index 000000000..096f3ebf8 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java @@ -0,0 +1,45 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.MenuType; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; + +public class CraftAccessLocationInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder { + + private final CraftAccessContainerObjectBuilder containerBuilder; + + public CraftAccessLocationInventoryViewBuilder(final MenuType handle, final CraftAccessContainerObjectBuilder containerBuilder) { + super(handle); + this.containerBuilder = containerBuilder; + } + + @Override + protected AbstractContainerMenu buildContainer(final ServerPlayer player) { + final ContainerLevelAccess access; + if (super.position == null) { + access = ContainerLevelAccess.create(player.level(), player.blockPosition()); + } else { + access = ContainerLevelAccess.create(super.world, super.position); + } + + return this.containerBuilder.build(player.nextContainerCounter(), player.getInventory(), access); + } + + @Override + public LocationInventoryViewBuilder copy() { + final CraftAccessLocationInventoryViewBuilder copy = new CraftAccessLocationInventoryViewBuilder<>(this.handle, this.containerBuilder); + copy.world = super.world; + copy.position = super.position; + copy.checkReachable = super.checkReachable; + copy.title = title; + return copy; + } + + public interface CraftAccessContainerObjectBuilder { + AbstractContainerMenu build(final int syncId, final Inventory inventory, ContainerLevelAccess access); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java new file mode 100644 index 000000000..262581444 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java @@ -0,0 +1,74 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuConstructor; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; +import org.jspecify.annotations.Nullable; + +public class CraftBlockEntityInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder { + + private final Block block; + private final @Nullable CraftTileInventoryBuilder builder; + + public CraftBlockEntityInventoryViewBuilder(final MenuType handle, final Block block, final @Nullable CraftTileInventoryBuilder builder) { + super(handle); + this.block = block; + this.builder = builder; + } + + @Override + protected AbstractContainerMenu buildContainer(final ServerPlayer player) { + if (this.world == null) { + this.world = player.level(); + } + + if (this.position == null) { + this.position = player.blockPosition(); + } + + final BlockEntity entity = this.world.getBlockEntity(position); + if (!(entity instanceof final MenuConstructor container)) { + return buildFakeTile(player); + } + + final AbstractContainerMenu atBlock = container.createMenu(player.nextContainerCounter(), player.getInventory(), player); + if (atBlock.getType() != super.handle) { + return buildFakeTile(player); + } + + return atBlock; + } + + private AbstractContainerMenu buildFakeTile(final ServerPlayer player) { + if (this.builder == null) { + return handle.create(player.nextContainerCounter(), player.getInventory()); + } + final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState()); + if (inventory instanceof final BlockEntity tile) { + tile.setLevel(this.world); + } + return inventory.createMenu(player.nextContainerCounter(), player.getInventory(), player); + } + + @Override + public LocationInventoryViewBuilder copy() { + final CraftBlockEntityInventoryViewBuilder copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder); + copy.world = this.world; + copy.position = this.position; + copy.checkReachable = super.checkReachable; + copy.title = title; + return copy; + } + + public interface CraftTileInventoryBuilder { + MenuProvider build(BlockPos blockPosition, BlockState blockData); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java new file mode 100644 index 000000000..331e3797a --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.ChestBlock; +import net.minecraft.world.level.block.DoubleBlockCombiner; +import net.minecraft.world.level.block.entity.ChestBlockEntity; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; + +public class CraftDoubleChestInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder { + + public CraftDoubleChestInventoryViewBuilder(final MenuType handle) { + super(handle); + } + + @Override + protected AbstractContainerMenu buildContainer(final ServerPlayer player) { + if (super.world == null) { + return handle.create(player.nextContainerCounter(), player.getInventory()); + } + + final ChestBlock chest = (ChestBlock) Blocks.CHEST; + final DoubleBlockCombiner.NeighborCombineResult result = chest.combine(super.world.getBlockState(super.position), super.world, super.position, false); + if (result instanceof DoubleBlockCombiner.NeighborCombineResult.Single) { + return handle.create(player.nextContainerCounter(), player.getInventory()); + } + + final MenuProvider combined = result.apply(ChestBlock.MENU_PROVIDER_COMBINER).orElse(null); + if (combined == null) { + return handle.create(player.nextContainerCounter(), player.getInventory()); + } + return combined.createMenu(player.nextContainerCounter(), player.getInventory(), player); + } + + @Override + public LocationInventoryViewBuilder copy() { + final CraftDoubleChestInventoryViewBuilder copy = new CraftDoubleChestInventoryViewBuilder<>(super.handle); + copy.world = this.world; + copy.position = this.position; + copy.checkReachable = super.checkReachable; + copy.title = title; + return copy; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java new file mode 100644 index 000000000..7f7518aa7 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java @@ -0,0 +1,78 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import com.google.common.base.Preconditions; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.MerchantMenu; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.inventory.CraftMerchant; +import org.bukkit.craftbukkit.inventory.CraftMerchantCustom; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.Merchant; +import org.bukkit.inventory.view.builder.MerchantInventoryViewBuilder; +import org.jspecify.annotations.Nullable; + +public class CraftMerchantInventoryViewBuilder extends CraftAbstractInventoryViewBuilder implements MerchantInventoryViewBuilder { + + private net.minecraft.world.item.trading.@Nullable Merchant merchant; + + public CraftMerchantInventoryViewBuilder(final MenuType handle) { + super(handle); + } + + @Override + public MerchantInventoryViewBuilder title(final Component title) { + return (MerchantInventoryViewBuilder) super.title(title); + } + + @Override + public MerchantInventoryViewBuilder merchant(final Merchant merchant) { + this.merchant = ((CraftMerchant) merchant).getMerchant(); + return this; + } + + @Override + public MerchantInventoryViewBuilder checkReachable(final boolean checkReachable) { + super.checkReachable = checkReachable; + return this; + } + + @Override + public V build(final HumanEntity player) { + Preconditions.checkArgument(player != null, "The given player must not be null"); + Preconditions.checkArgument(this.title != null, "The given title must not be null"); + Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity"); + final CraftHumanEntity craftHuman = (CraftHumanEntity) player; + Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer"); + final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle(); + + final MerchantMenu container; + if (this.merchant == null) { + container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), new CraftMerchantCustom(title).getMerchant()); + } else { + container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), this.merchant); + } + + container.checkReachable = super.checkReachable; + container.setTitle(PaperAdventure.asVanilla(this.title)); + return (V) container.getBukkitView(); + } + + @Override + protected AbstractContainerMenu buildContainer(final ServerPlayer player) { + throw new UnsupportedOperationException("buildContainer is not supported for CraftMerchantInventoryViewBuilder"); + } + + @Override + public MerchantInventoryViewBuilder copy() { + final CraftMerchantInventoryViewBuilder copy = new CraftMerchantInventoryViewBuilder<>(super.handle); + copy.checkReachable = super.checkReachable; + copy.merchant = this.merchant; + copy.title = title; + return copy; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java new file mode 100644 index 000000000..e528facbe --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.MenuType; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.view.builder.InventoryViewBuilder; + +public class CraftStandardInventoryViewBuilder extends CraftAbstractInventoryViewBuilder { + + public CraftStandardInventoryViewBuilder(final MenuType handle) { + super(handle); + } + + @Override + protected AbstractContainerMenu buildContainer(final ServerPlayer player) { + return super.handle.create(player.nextContainerCounter(), player.getInventory()); + } + + @Override + public InventoryViewBuilder copy() { + final CraftStandardInventoryViewBuilder copy = new CraftStandardInventoryViewBuilder<>(handle); + copy.title = this.title; + return copy; + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/package-info.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/package-info.java new file mode 100644 index 000000000..157ce9fd7 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/package-info.java @@ -0,0 +1,4 @@ +@NullMarked +package org.bukkit.craftbukkit.inventory.view.builder; + +import org.jspecify.annotations.NullMarked; From c2f24e1567a3ac576c31c7e4fab0d56988e52a56 Mon Sep 17 00:00:00 2001 From: Strokkur24 <133226102+Strokkur424@users.noreply.github.com> Date: Sat, 11 Jan 2025 22:29:16 +0100 Subject: [PATCH 033/203] Feat: Add 'with' methods to CommandSourceStack (#11868) --- .../command/brigadier/CommandSourceStack.java | 22 +++++++++++++ ...y-type-tags-suggestions-in-selectors.patch | 4 +-- .../commands/CommandSourceStack.java.patch | 31 +++++++++++++++++++ .../brigadier/PaperCommandSourceStack.java | 16 +++++++--- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java index ac6f5b754..109c0a89e 100644 --- a/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java @@ -1,5 +1,7 @@ package io.papermc.paper.command.brigadier; +import com.mojang.brigadier.RedirectModifier; +import com.mojang.brigadier.tree.CommandNode; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; @@ -48,4 +50,24 @@ public interface CommandSourceStack { * @return entity that executes this command */ @Nullable Entity getExecutor(); + + /** + * Creates a new CommandSourceStack object with a different location for redirecting commands to other nodes. + * + * @param location The location to create a new CommandSourceStack object with + * @return The newly created CommandSourceStack + * @see #getLocation() + * @see com.mojang.brigadier.builder.ArgumentBuilder#fork(CommandNode, RedirectModifier) + */ + CommandSourceStack withLocation(Location location); + + /** + * Creates a new CommandSourceStack object with a different executor for redirecting commands to other nodes. + * + * @param executor The executing entity to create a new CommandSourceStack object with + * @return The newly created CommandSourceStack + * @see #getExecutor() + * @see com.mojang.brigadier.builder.ArgumentBuilder#fork(CommandNode, RedirectModifier) + */ + CommandSourceStack withExecutor(Entity executor); } diff --git a/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch b/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch index cd578f9f5..b587b90ed 100644 --- a/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch @@ -10,10 +10,10 @@ when if this was fixed on the client, that wouldn't be needed. Mojira Issue: https://bugs.mojang.com/browse/MC-235045 diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java -index 704a63890a06d793f8ac3452838917e7c7335232..75262c8c9eaecb4a88a94f4076d67119c67a97da 100644 +index cf923441da598637be74a5ffa4b4f948e01ff532..cbf32be9235921ebcaca88225120c2ca70a72771 100644 --- a/net/minecraft/commands/CommandSourceStack.java +++ b/net/minecraft/commands/CommandSourceStack.java -@@ -652,4 +652,20 @@ public class CommandSourceStack implements ExecutionCommandSource Date: Sat, 11 Jan 2025 22:46:36 +0100 Subject: [PATCH 034/203] Disallow calling JavaPlugin#getCommand during onEnable for Paper plugins (#11914) Co-authored-by: leguan --- .../org/bukkit/plugin/java/JavaPlugin.java | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java index 60a8a2cca..a04100646 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -26,7 +26,6 @@ import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.PluginBase; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginLoader; -import org.bukkit.plugin.PluginLogger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,30 +40,27 @@ public abstract class JavaPlugin extends PluginBase { private Server server = null; private File file = null; private PluginDescriptionFile description = null; - private io.papermc.paper.plugin.configuration.PluginMeta pluginMeta = null; // Paper + private io.papermc.paper.plugin.configuration.PluginMeta pluginMeta = null; private File dataFolder = null; private ClassLoader classLoader = null; private boolean naggable = true; private FileConfiguration newConfig = null; private File configFile = null; - private Logger logger = null; // Paper - PluginLogger -> Logger - // Paper start - lifecycle events + private Logger logger = null; @SuppressWarnings("deprecation") private final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager lifecycleEventManager = org.bukkit.Bukkit.getUnsafe().createPluginLifecycleEventManager(this, () -> this.allowsLifecycleRegistration); private boolean allowsLifecycleRegistration = true; - // Paper end + private boolean isBeingEnabled = false; public JavaPlugin() { - // Paper start if (this.getClass().getClassLoader() instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader) { configuredPluginClassLoader.init(this); } else { throw new IllegalStateException("JavaPlugin requires to be created by a valid classloader."); } - // Paper end } - @Deprecated(forRemoval = true) // Paper + @Deprecated(forRemoval = true) protected JavaPlugin(@NotNull final JavaPluginLoader loader, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file) { final ClassLoader classLoader = this.getClass().getClassLoader(); if (classLoader instanceof PluginClassLoader) { @@ -94,7 +90,7 @@ public abstract class JavaPlugin extends PluginBase { */ @NotNull @Override - @Deprecated(forRemoval = true) // Paper + @Deprecated(forRemoval = true) public final PluginLoader getPluginLoader() { return loader; } @@ -111,8 +107,7 @@ public abstract class JavaPlugin extends PluginBase { } /** - * Returns a value indicating whether or not this plugin is currently - * enabled + * Returns a value indicating whether this plugin is currently enabled * * @return true if this plugin is enabled, otherwise false */ @@ -278,22 +273,25 @@ public abstract class JavaPlugin extends PluginBase { * * @param enabled true if enabled, otherwise false */ - @org.jetbrains.annotations.ApiStatus.Internal // Paper - public final void setEnabled(final boolean enabled) { // Paper + @org.jetbrains.annotations.ApiStatus.Internal + public final void setEnabled(final boolean enabled) { if (isEnabled != enabled) { isEnabled = enabled; if (isEnabled) { - try { // Paper - lifecycle events - onEnable(); - } finally { this.allowsLifecycleRegistration = false; } // Paper - lifecycle events + this.isBeingEnabled = true; + try { + onEnable(); + } finally { + this.allowsLifecycleRegistration = false; + this.isBeingEnabled = false; + } } else { onDisable(); } } } - // Paper start private static class DummyPluginLoaderImplHolder { private static final PluginLoader INSTANCE = net.kyori.adventure.util.Services.service(PluginLoader.class) .orElseThrow(); @@ -303,16 +301,15 @@ public abstract class JavaPlugin extends PluginBase { this.pluginMeta = description; } public final void init(@NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader, @Nullable io.papermc.paper.plugin.configuration.PluginMeta configuration, @NotNull Logger logger) { - // Paper end - this.loader = DummyPluginLoaderImplHolder.INSTANCE; // Paper + this.loader = DummyPluginLoaderImplHolder.INSTANCE; this.server = server; this.file = file; this.description = description; this.dataFolder = dataFolder; this.classLoader = classLoader; this.configFile = new File(dataFolder, "config.yml"); - this.pluginMeta = configuration; // Paper - this.logger = logger; // Paper + this.pluginMeta = configuration; + this.logger = logger; } /** @@ -339,9 +336,18 @@ public abstract class JavaPlugin extends PluginBase { * * @param name name or alias of the command * @return the plugin command if found, otherwise null + * @throws UnsupportedOperationException if this plugin is a paper plugin and the method is called in {@link #onEnable()} */ @Nullable public PluginCommand getCommand(@NotNull String name) { + if (this.isBeingEnabled && !(pluginMeta instanceof PluginDescriptionFile)) { + throw new UnsupportedOperationException(""" + You are trying to call JavaPlugin#getCommand on a Paper plugin during startup: + you are probably trying to get a command you tried to define in paper-plugin.yml. + Paper plugins do not support YAML-based command declarations! + Please check the documentation for more information on how to define commands in Paper plugins: https://docs.papermc.io/paper/dev/getting-started/paper-plugins#commands + """); + } String alias = name.toLowerCase(Locale.ROOT); PluginCommand command = getServer().getPluginCommand(alias); @@ -429,10 +435,10 @@ public abstract class JavaPlugin extends PluginBase { throw new IllegalArgumentException(clazz + " does not extend " + JavaPlugin.class); } final ClassLoader cl = clazz.getClassLoader(); - if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) { // Paper - throw new IllegalArgumentException(clazz + " is not initialized by a " + io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader.class); // Paper + if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) { + throw new IllegalArgumentException(clazz + " is not initialized by a " + io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader.class); } - JavaPlugin plugin = configuredPluginClassLoader.getPlugin(); // Paper + JavaPlugin plugin = configuredPluginClassLoader.getPlugin(); if (plugin == null) { throw new IllegalStateException("Cannot get plugin for " + clazz + " from a static initializer"); } @@ -455,20 +461,18 @@ public abstract class JavaPlugin extends PluginBase { public static JavaPlugin getProvidingPlugin(@NotNull Class clazz) { Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin"); final ClassLoader cl = clazz.getClassLoader(); - if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) { // Paper - throw new IllegalArgumentException(clazz + " is not provided by a " + io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader.class); // Paper + if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) { + throw new IllegalArgumentException(clazz + " is not provided by a " + io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader.class); } - JavaPlugin plugin = configuredPluginClassLoader.getPlugin(); // Paper + JavaPlugin plugin = configuredPluginClassLoader.getPlugin(); if (plugin == null) { throw new IllegalStateException("Cannot get plugin for " + clazz + " from a static initializer"); } return plugin; } - // Paper start - lifecycle events @Override public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager() { return this.lifecycleEventManager; } - // Paper end - lifecycle events } From 08ac057fda77b812ec155566e7838c347c290b94 Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Sun, 12 Jan 2025 03:17:46 +0200 Subject: [PATCH 035/203] Rename getPotentialBedLocation to getPotentialRespawnLocation (#11950) --- .../java/org/bukkit/entity/HumanEntity.java | 18 +++++++++++++++++- .../craftbukkit/entity/CraftHumanEntity.java | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) 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 f04a6bf9e..34538999e 100644 --- a/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java @@ -453,9 +453,25 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * is still valid. * * @return Bed Location if has slept in one, otherwise null. + * @see #getPotentialRespawnLocation() + * @deprecated Misleading name. This method also returns the location of + * respawn anchors. */ @Nullable - public Location getPotentialBedLocation(); + @Deprecated(since = "1.21.4") + default Location getPotentialBedLocation() { + return this.getPotentialRespawnLocation(); + } + + /** + * Gets the Location where the player will spawn at, null if they + * don't have a valid respawn point. This method will not attempt + * to validate if the current respawn location is still valid. + * + * @return respawn location if exists, otherwise null. + */ + @Nullable + Location getPotentialRespawnLocation(); // Paper end // Paper start /** 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 cafd8c534..a39615754 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 @@ -154,7 +154,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { // Paper start - Potential bed api @Override - public Location getPotentialBedLocation() { + public Location getPotentialRespawnLocation() { ServerPlayer handle = (ServerPlayer) getHandle(); BlockPos bed = handle.getRespawnPosition(); if (bed == null) { From 9746d73ade8c64edab0937d7d065e35faa72dfeb Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 12 Jan 2025 15:29:07 +0100 Subject: [PATCH 036/203] Add back known movement check --- .../minecraft/world/entity/projectile/Projectile.java.patch | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch index 9052fd22b..01591a830 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -54,11 +54,14 @@ } this.leftOwner = compound.getBoolean("LeftOwner"); -@@ -175,13 +_,22 @@ +@@ -175,13 +_,25 @@ float f2 = Mth.cos(y * (float) (Math.PI / 180.0)) * Mth.cos(x * (float) (Math.PI / 180.0)); this.shoot(f, f1, f2, velocity, inaccuracy); Vec3 knownMovement = shooter.getKnownMovement(); + // Paper start - allow disabling relative velocity ++ if (Double.isNaN(knownMovement.x) || Double.isNaN(knownMovement.y) || Double.isNaN(knownMovement.z)) { ++ knownMovement = new Vec3(0, 0, 0); ++ } + if (!shooter.level().paperConfig().misc.disableRelativeProjectileVelocity) { this.setDeltaMovement(this.getDeltaMovement().add(knownMovement.x, shooter.onGround() ? 0.0 : knownMovement.y, knownMovement.z)); + } From e5542cfdc32c0b0b53dd3df1dbf2d60597440105 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 12 Jan 2025 17:49:49 +0100 Subject: [PATCH 037/203] Hide unnecessary decorated pot data (#11957) Prevent decorated pots from sending their contents to clients as contents are not needed for rendering. --- .../entity/DecoratedPotBlockEntity.java.patch | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch index 08a08744a..8fc38f243 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch @@ -49,3 +49,28 @@ public static final String TAG_SHERDS = "sherds"; public static final String TAG_ITEM = "item"; public static final int EVENT_POT_WOBBLES = 1; +@@ -41,8 +_,8 @@ + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + this.decorations.save(tag); +- if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) { +- tag.put("item", this.item.save(registries)); ++ if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data ++ tag.put("item", this.item.save(registries)); // Paper - diff on change - hide unnecessary update data + } + } + +@@ -66,7 +_,12 @@ + + @Override + public CompoundTag getUpdateTag(HolderLookup.Provider registries) { +- return this.saveCustomOnly(registries); ++ // Paper start - hide unnecessary update data ++ // Like chests, decorated pots should not allow clients to inspect their contents without breaking them. ++ final CompoundTag compoundTag = new CompoundTag(); ++ this.decorations.save(compoundTag); ++ return compoundTag; ++ // Paper end - hide unnecessary update data + } + + public Direction getDirection() { From eb4db794eb2b2837ad101716034bc9a4f0fa2629 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sun, 12 Jan 2025 17:50:08 +0100 Subject: [PATCH 038/203] Make CommandSourceStack respect hidden players (#11898) --- ...y-type-tags-suggestions-in-selectors.patch | 23 +------------------ .../commands/CommandSourceStack.java.patch | 9 ++++++++ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch b/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch index b587b90ed..2d6d532ce 100644 --- a/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch @@ -60,7 +60,7 @@ index fa8c5ba4e0efd0c36613aaa8eaafba0cb70ceb87..19ccf3abf14c67f72a1ca065e4a304f5 } diff --git a/net/minecraft/commands/arguments/EntityArgument.java b/net/minecraft/commands/arguments/EntityArgument.java -index 0a01df6ebd14afe79bc76364cb1df5e0c5c08074..7a06ad9940d25e163178370bfa9ccc3bbd3d1189 100644 +index 0a01df6ebd14afe79bc76364cb1df5e0c5c08074..77a68052c7653aee54c60f4bded9fa5337e3e4db 100644 --- a/net/minecraft/commands/arguments/EntityArgument.java +++ b/net/minecraft/commands/arguments/EntityArgument.java @@ -138,7 +138,7 @@ public class EntityArgument implements ArgumentType { @@ -72,27 +72,6 @@ index 0a01df6ebd14afe79bc76364cb1df5e0c5c08074..7a06ad9940d25e163178370bfa9ccc3b // Paper end - Fix EntityArgument permissions try { -@@ -149,7 +149,19 @@ public class EntityArgument implements ArgumentType { - return entitySelectorParser.fillSuggestions( - builder, - offsetBuilder -> { -- Collection onlinePlayerNames = sharedSuggestionProvider.getOnlinePlayerNames(); -+ // Paper start - tell clients to ask server for suggestions for EntityArguments -+ final Collection onlinePlayerNames; -+ if (sharedSuggestionProvider instanceof CommandSourceStack commandSourceStack && commandSourceStack.getEntity() instanceof ServerPlayer sourcePlayer) { -+ onlinePlayerNames = new java.util.ArrayList<>(); -+ for (final ServerPlayer player : commandSourceStack.getServer().getPlayerList().getPlayers()) { -+ if (sourcePlayer.getBukkitEntity().canSee(player.getBukkitEntity())) { -+ onlinePlayerNames.add(player.getGameProfile().getName()); -+ } -+ } -+ } else { -+ onlinePlayerNames = sharedSuggestionProvider.getOnlinePlayerNames(); -+ } -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - Iterable iterable = (Iterable)(this.playersOnly - ? onlinePlayerNames - : Iterables.concat(onlinePlayerNames, sharedSuggestionProvider.getSelectedEntities())); diff --git a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java index a6f232747df631f6afe440606bea94c588f1a0dd..fb42630741674c6cbd20b7d45d78dea1dc73a78f 100644 --- a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java diff --git a/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch b/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch index bac6f4b64..488821280 100644 --- a/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch @@ -123,6 +123,15 @@ } } +@@ -523,7 +_,7 @@ + + @Override + public Collection getOnlinePlayerNames() { +- return Lists.newArrayList(this.server.getPlayerNames()); ++ return this.entity instanceof ServerPlayer sourcePlayer && !sourcePlayer.getBukkitEntity().hasPermission("paper.bypass-visibility.tab-completion") ? this.getServer().getPlayerList().getPlayers().stream().filter(serverPlayer -> sourcePlayer.getBukkitEntity().canSee(serverPlayer.getBukkitEntity())).map(serverPlayer -> serverPlayer.getGameProfile().getName()).toList() : Lists.newArrayList(this.server.getPlayerNames()); // Paper - Make CommandSourceStack respect hidden players + } + + @Override @@ -598,4 +_,16 @@ public boolean isSilent() { return this.silent; From 76617ddf435a4a0dadfea490ea8de12f7fbe737d Mon Sep 17 00:00:00 2001 From: caramel Date: Mon, 13 Jan 2025 01:50:22 +0900 Subject: [PATCH 039/203] Add EntityEffectTickEvent (#11838) --- .../event/entity/EntityEffectTickEvent.java | 75 +++++++++++++++++++ .../effect/HealOrHarmMobEffect.java.patch | 5 +- .../world/effect/MobEffect.java.patch | 10 +++ .../world/effect/MobEffectInstance.java.patch | 10 +++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/entity/EntityEffectTickEvent.java create mode 100644 paper-server/patches/sources/net/minecraft/world/effect/MobEffect.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityEffectTickEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityEffectTickEvent.java new file mode 100644 index 000000000..fef69314f --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityEffectTickEvent.java @@ -0,0 +1,75 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * An event that is triggered when an entity receives a potion effect instantly + * or when the potion effect is applied on each tick (e.g. every 25 ticks for Poison level 1). + *

+ * For example, this event may be called when an entity regenerates health + * or takes poison damage as a result of a potion effect. + */ +@NullMarked +public class EntityEffectTickEvent extends EntityEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final PotionEffectType type; + private final int amplifier; + private boolean cancelled; + + @ApiStatus.Internal + public EntityEffectTickEvent(final LivingEntity entity, final PotionEffectType type, final int amplifier) { + super(entity); + this.type = type; + this.amplifier = amplifier; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) super.getEntity(); + } + + /** + * Gets the type of the potion effect associated with this event. + * + * @return the {@link PotionEffectType} of the effect + */ + public PotionEffectType getType() { + return type; + } + + /** + * Gets the amplifier level of the potion effect associated with this event. + * + * @return the amplifier level of the potion effect + */ + public int getAmplifier() { + return amplifier; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch index 040430b44..274a71976 100644 --- a/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/effect/HealOrHarmMobEffect.java.patch @@ -9,8 +9,11 @@ } else { entity.hurtServer(level, entity.damageSources().magic(), 6 << amplifier); } -@@ -30,7 +_,7 @@ +@@ -28,9 +_,10 @@ + public void applyInstantenousEffect( + ServerLevel level, @Nullable Entity source, @Nullable Entity indirectSource, LivingEntity entity, int amplifier, double health ) { ++ if (!new io.papermc.paper.event.entity.EntityEffectTickEvent(entity.getBukkitLivingEntity(), org.bukkit.craftbukkit.potion.CraftPotionEffectType.minecraftToBukkit(this), amplifier).callEvent()) { return; } // Paper - Add EntityEffectTickEvent if (this.isHarm == entity.isInvertedHealAndHarm()) { int i = (int)(health * (4 << amplifier) + 0.5); - entity.heal(i); diff --git a/paper-server/patches/sources/net/minecraft/world/effect/MobEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/MobEffect.java.patch new file mode 100644 index 000000000..20dfc7fa7 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/effect/MobEffect.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/effect/MobEffect.java ++++ b/net/minecraft/world/effect/MobEffect.java +@@ -76,6 +_,7 @@ + public void applyInstantenousEffect( + ServerLevel level, @Nullable Entity source, @Nullable Entity indirectSource, LivingEntity entity, int amplifier, double health + ) { ++ if (!new io.papermc.paper.event.entity.EntityEffectTickEvent(entity.getBukkitLivingEntity(), org.bukkit.craftbukkit.potion.CraftPotionEffectType.minecraftToBukkit(this), amplifier).callEvent()) { return; } // Paper - Add EntityEffectTickEvent + this.applyEffectTick(level, entity, amplifier); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch new file mode 100644 index 000000000..7cdda27b0 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/effect/MobEffectInstance.java ++++ b/net/minecraft/world/effect/MobEffectInstance.java +@@ -216,6 +_,7 @@ + int i = this.isInfiniteDuration() ? entity.tickCount : this.duration; + if (entity.level() instanceof ServerLevel serverLevel + && this.effect.value().shouldApplyEffectTickThisTick(i, this.amplifier) ++ && new io.papermc.paper.event.entity.EntityEffectTickEvent(entity.getBukkitLivingEntity(), org.bukkit.craftbukkit.potion.CraftPotionEffectType.minecraftHolderToBukkit(this.effect), this.amplifier).callEvent() // Paper - Add EntityEffectTickEvent + && !this.effect.value().applyEffectTick(serverLevel, entity, this.amplifier)) { + entity.removeEffect(this.effect); + } From 86c6308faf28dedeeeecdce03af283a47a076a71 Mon Sep 17 00:00:00 2001 From: Creeam <102713261+HaHaWTH@users.noreply.github.com> Date: Sun, 12 Jan 2025 08:55:45 -0800 Subject: [PATCH 040/203] Fix locate command dist overflow/underflow (#11956) --- .../minecraft/server/commands/LocateCommand.java.patch | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch diff --git a/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch new file mode 100644 index 000000000..455b4cb07 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/commands/LocateCommand.java ++++ b/net/minecraft/server/commands/LocateCommand.java +@@ -202,6 +_,6 @@ + private static float dist(int x1, int z1, int x2, int z2) { + int i = x2 - x1; + int i1 = z2 - z1; +- return Mth.sqrt(i * i + i1 * i1); ++ return (float) Math.hypot(i, i1); // Paper - Fix MC-177381 + } + } From 2ea6aee343284afb2224774cf6a7f97a5f8d4327 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sun, 12 Jan 2025 21:49:25 +0100 Subject: [PATCH 041/203] Deprecate Turtle#isDigging (#11959) --- paper-api/src/main/java/org/bukkit/entity/Turtle.java | 8 +++++--- .../level/block/entity/BrewingStandBlockEntity.java.patch | 5 +++-- .../java/org/bukkit/craftbukkit/entity/CraftTurtle.java | 7 ------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Turtle.java b/paper-api/src/main/java/org/bukkit/entity/Turtle.java index aa83615a0..3b26e9e48 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Turtle.java +++ b/paper-api/src/main/java/org/bukkit/entity/Turtle.java @@ -22,7 +22,6 @@ public interface Turtle extends Animals { */ boolean isLayingEgg(); - // Paper start /** * Get the turtle's home location * @@ -49,8 +48,12 @@ public interface Turtle extends Animals { * Get if turtle is digging to lay eggs * * @return True if digging + * @deprecated in favor of {@link #isLayingEgg()} */ - boolean isDigging(); + @Deprecated(since = "1.21.4") + default boolean isDigging() { + return this.isLayingEgg(); + } /** * Set if turtle is carrying egg @@ -58,5 +61,4 @@ public interface Turtle extends Animals { * @param hasEgg True if carrying egg */ void setHasEgg(boolean hasEgg); - // Paper end } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch index 15e9dfa1d..f1b0523e9 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java.patch @@ -100,10 +100,11 @@ } else if (!isBrewable || !itemStack1.is(blockEntity.ingredient)) { blockEntity.brewTime = 0; } -@@ -114,6 +_,14 @@ +@@ -113,7 +_,14 @@ + setChanged(level, pos, state); } else if (isBrewable && blockEntity.fuel > 0) { blockEntity.fuel--; - blockEntity.brewTime = 400; +- blockEntity.brewTime = 400; + // CraftBukkit start + org.bukkit.event.block.BrewingStartEvent event = new org.bukkit.event.block.BrewingStartEvent( + org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), 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 d44e6f4bb..00e59cdc8 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 @@ -29,7 +29,6 @@ public class CraftTurtle extends CraftAnimals implements Turtle { return this.getHandle().isLayingEgg(); } - // Paper start @Override public org.bukkit.Location getHome() { return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().level(), this.getHandle().getHomePos()); @@ -45,14 +44,8 @@ public class CraftTurtle extends CraftAnimals implements Turtle { return this.getHandle().isGoingHome(); } - @Override - public boolean isDigging() { - return this.getHandle().isLayingEgg(); - } - @Override public void setHasEgg(boolean hasEgg) { this.getHandle().setHasEgg(hasEgg); } - // Paper end } From ad74b673fad856aac3f61a600504be772a51506e Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:56:11 -0300 Subject: [PATCH 042/203] Fix client visual desync if cooldown events are cancelled (#11892) --- .../world/item/ServerItemCooldowns.java.patch | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch index 6e1f3fcec..bbc0b1065 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch @@ -1,10 +1,18 @@ --- a/net/minecraft/world/item/ServerItemCooldowns.java +++ b/net/minecraft/world/item/ServerItemCooldowns.java -@@ -11,6 +_,39 @@ +@@ -11,6 +_,50 @@ this.player = player; } + // Paper start - Add PlayerItemCooldownEvent ++ private int getCurrentCooldown(final ResourceLocation groupId) { ++ final net.minecraft.world.item.ItemCooldowns.CooldownInstance cooldownInstance = this.cooldowns.get(groupId); ++ if (cooldownInstance == null) { ++ return 0; ++ } ++ return Math.max(0, cooldownInstance.endTime() - this.tickCount); ++ } ++ + @Override + public void addCooldown(ItemStack item, int duration) { + final ResourceLocation cooldownGroup = this.getCooldownGroup(item); @@ -15,7 +23,9 @@ + duration + ); + if (event.callEvent()) { -+ super.addCooldown(cooldownGroup, event.getCooldown(), false); ++ this.addCooldown(cooldownGroup, event.getCooldown(), false); ++ } else { ++ this.player.connection.send(new ClientboundCooldownPacket(cooldownGroup, this.getCurrentCooldown(cooldownGroup))); + } + } + @@ -28,6 +38,7 @@ + duration + ); + if (!event.callEvent()) { ++ this.player.connection.send(new ClientboundCooldownPacket(groupId, this.getCurrentCooldown(groupId))); + return; + } + From 50c2c59c4e0875da1ec8c73276bbeb874517fd26 Mon Sep 17 00:00:00 2001 From: Emily Date: Sun, 12 Jan 2025 19:49:29 -0300 Subject: [PATCH 043/203] Fix unstable Suggestion comparison by sorting int suggestions before text ones (#11941) --- .../suggestion/IntegerSuggestion.java.patch | 19 +++++++++++ .../suggestion/Suggestion.java.patch | 32 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 paper-server/patches/sources/com/mojang/brigadier/suggestion/IntegerSuggestion.java.patch create mode 100644 paper-server/patches/sources/com/mojang/brigadier/suggestion/Suggestion.java.patch diff --git a/paper-server/patches/sources/com/mojang/brigadier/suggestion/IntegerSuggestion.java.patch b/paper-server/patches/sources/com/mojang/brigadier/suggestion/IntegerSuggestion.java.patch new file mode 100644 index 000000000..e773c2937 --- /dev/null +++ b/paper-server/patches/sources/com/mojang/brigadier/suggestion/IntegerSuggestion.java.patch @@ -0,0 +1,19 @@ +--- a/com/mojang/brigadier/suggestion/IntegerSuggestion.java ++++ b/com/mojang/brigadier/suggestion/IntegerSuggestion.java +@@ -53,7 +_,7 @@ + + @Override + public int compareTo(final Suggestion o) { +- if (o instanceof IntegerSuggestion) { ++ if (false && o instanceof IntegerSuggestion) { // Paper - fix unstable Suggestion comparison + return Integer.compare(value, ((IntegerSuggestion) o).value); + } + return super.compareTo(o); +@@ -61,6 +_,6 @@ + + @Override + public int compareToIgnoreCase(final Suggestion b) { +- return compareTo(b); ++ return super.compareToIgnoreCase(b); // Paper - fix unstable Suggestion comparison + } + } diff --git a/paper-server/patches/sources/com/mojang/brigadier/suggestion/Suggestion.java.patch b/paper-server/patches/sources/com/mojang/brigadier/suggestion/Suggestion.java.patch new file mode 100644 index 000000000..1449e3a25 --- /dev/null +++ b/paper-server/patches/sources/com/mojang/brigadier/suggestion/Suggestion.java.patch @@ -0,0 +1,32 @@ +--- a/com/mojang/brigadier/suggestion/Suggestion.java ++++ b/com/mojang/brigadier/suggestion/Suggestion.java +@@ -76,13 +_,27 @@ + '}'; + } + ++ // Paper start - fix unstable Suggestion comparison ++ private static int compare0(final Suggestion lhs, final Suggestion rhs, final java.util.Comparator textComparator) { ++ if (lhs instanceof final IntegerSuggestion lis && rhs instanceof final IntegerSuggestion ris) { ++ return Integer.compare(lis.getValue(), ris.getValue()); ++ } else if (lhs instanceof IntegerSuggestion) { ++ return -1; ++ } else if (rhs instanceof IntegerSuggestion) { ++ return 1; ++ } else { ++ return textComparator.compare(lhs.text, rhs.text); ++ } ++ } ++ // Paper end - fix unstable Suggestion comparison ++ + @Override + public int compareTo(final Suggestion o) { +- return text.compareTo(o.text); ++ return compare0(this, o, java.util.Comparator.naturalOrder()); // Paper - fix unstable Suggestion comparison + } + + public int compareToIgnoreCase(final Suggestion b) { +- return text.compareToIgnoreCase(b.text); ++ return compare0(this, b, String.CASE_INSENSITIVE_ORDER); // Paper - fix unstable Suggestion comparison + } + + public Suggestion expand(final String command, final StringRange range) { From 3709150bc107ad15f4d824c88b919e7001feec0d Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:56:56 +0200 Subject: [PATCH 044/203] Expose all possible block data states (#11958) --- .../main/java/org/bukkit/block/BlockType.java | 19 +++++++++++++++++++ .../craftbukkit/block/CraftBlockType.java | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/block/BlockType.java b/paper-api/src/main/java/org/bukkit/block/BlockType.java index 6e24b05c9..d8fde88e3 100644 --- a/paper-api/src/main/java/org/bukkit/block/BlockType.java +++ b/paper-api/src/main/java/org/bukkit/block/BlockType.java @@ -1,5 +1,6 @@ package org.bukkit.block; +import java.util.Collection; import java.util.function.Consumer; import org.bukkit.Keyed; import org.bukkit.Material; @@ -120,6 +121,7 @@ import org.bukkit.inventory.ItemType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Unmodifiable; /** * While this API is in a public interface, it is not intended for use by @@ -169,6 +171,15 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran @Override B createBlockData(); + /** + * Creates a collection of {@link BlockData} instances for this block type, with all + * possible combinations of properties values. + * + * @return new block data collection + */ + @Override + @Unmodifiable @NotNull Collection createBlockDataStates(); + /** * Creates a new {@link BlockData} instance for this block type, with all * properties initialized to unspecified defaults, except for those provided @@ -3480,6 +3491,14 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran @NotNull BlockData createBlockData(); + /** + * Creates a collection of {@link BlockData} instances for this block type, with all + * possible combinations of properties values. + * + * @return new block data collection + */ + @Unmodifiable @NotNull Collection createBlockDataStates(); + /** * Creates a new {@link BlockData} instance for this block type, with all * properties initialized to unspecified defaults, except for those provided diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java index 90fe14f10..6827c30a2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockType.java @@ -3,7 +3,9 @@ package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Collection; import java.util.function.Consumer; +import com.google.common.collect.ImmutableList; import net.minecraft.core.BlockPos; import net.minecraft.core.registries.Registries; import net.minecraft.world.InteractionHand; @@ -147,6 +149,16 @@ public class CraftBlockType implements BlockType.Typed, return this.createBlockData((String) null); } + @Override + public @NotNull Collection createBlockDataStates() { + final ImmutableList possibleStates = this.block.getStateDefinition().getPossibleStates(); + final ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(possibleStates.size()); + for (final BlockState possibleState : possibleStates) { + builder.add(this.blockDataClass.cast(possibleState.createCraftBlockData())); + } + return builder.build(); + } + @Override public B createBlockData(Consumer consumer) { B data = this.createBlockData(); From 5e23d28ad280b2955002a159b4f4235e2f326184 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 12 Jan 2025 15:07:24 -0800 Subject: [PATCH 045/203] Remove entity tag selector tag completion fix (#11964) The fix was causing too many issues, it really needs a client-side fix MC-235045 --- ...y-type-tags-suggestions-in-selectors.patch | 131 ------------------ ...-Oversized-block-entities-in-chunks.patch} | 0 ...10-optimize-dirt-and-snow-spreading.patch} | 0 ...-getChunkAt-calls-for-loaded-chunks.patch} | 0 ...Optimize-Bit-Operations-by-inlining.patch} | 0 ...> 0013-Remove-streams-from-hot-code.patch} | 0 ...er-Remove-Streams-Optimized-collect.patch} | 0 ...> 0015-Rewrite-dataconverter-system.patch} | 2 +- ... 0016-Moonrise-optimisation-patches.patch} | 2 +- ...r-desync-when-new-players-are-added.patch} | 0 ...-Eigencraft-redstone-implementation.patch} | 0 ...ate-Current-redstone-implementation.patch} | 0 ...ove-exact-choice-recipe-ingredients.patch} | 0 ...data-to-disk-if-it-serializes-witho.patch} | 2 +- ...22-Entity-load-save-limit-per-chunk.patch} | 0 ...ulate-regionfile-header-if-it-is-co.patch} | 4 +- ...Incremental-chunk-and-player-saving.patch} | 4 +- ...=> 0025-Optimise-general-POI-access.patch} | 0 ...0026-Optional-per-player-mob-spawns.patch} | 2 +- ...g-PreCreatureSpawnEvent-with-per-pl.patch} | 2 +- ...pers.patch => 0028-Optimize-Hoppers.patch} | 2 +- ...n-checking-in-player-move-packet-ha.patch} | 2 +- .../configuration/GlobalConfiguration.java | 1 - .../configuration/RemovedConfigurations.java | 3 +- 24 files changed, 13 insertions(+), 144 deletions(-) delete mode 100644 paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch rename paper-server/patches/features/{0010-Handle-Oversized-block-entities-in-chunks.patch => 0009-Handle-Oversized-block-entities-in-chunks.patch} (100%) rename paper-server/patches/features/{0011-optimize-dirt-and-snow-spreading.patch => 0010-optimize-dirt-and-snow-spreading.patch} (100%) rename paper-server/patches/features/{0012-Optimise-getChunkAt-calls-for-loaded-chunks.patch => 0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch} (100%) rename paper-server/patches/features/{0013-Optimize-Bit-Operations-by-inlining.patch => 0012-Optimize-Bit-Operations-by-inlining.patch} (100%) rename paper-server/patches/features/{0014-Remove-streams-from-hot-code.patch => 0013-Remove-streams-from-hot-code.patch} (100%) rename paper-server/patches/features/{0015-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch => 0014-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch} (100%) rename paper-server/patches/features/{0016-Rewrite-dataconverter-system.patch => 0015-Rewrite-dataconverter-system.patch} (99%) rename paper-server/patches/features/{0017-Moonrise-optimisation-patches.patch => 0016-Moonrise-optimisation-patches.patch} (99%) rename paper-server/patches/features/{0018-Fix-entity-tracker-desync-when-new-players-are-added.patch => 0017-Fix-entity-tracker-desync-when-new-players-are-added.patch} (100%) rename paper-server/patches/features/{0019-Eigencraft-redstone-implementation.patch => 0018-Eigencraft-redstone-implementation.patch} (100%) rename paper-server/patches/features/{0020-Add-Alternate-Current-redstone-implementation.patch => 0019-Add-Alternate-Current-redstone-implementation.patch} (100%) rename paper-server/patches/features/{0021-Improve-exact-choice-recipe-ingredients.patch => 0020-Improve-exact-choice-recipe-ingredients.patch} (100%) rename paper-server/patches/features/{0022-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch => 0021-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch} (98%) rename paper-server/patches/features/{0023-Entity-load-save-limit-per-chunk.patch => 0022-Entity-load-save-limit-per-chunk.patch} (100%) rename paper-server/patches/features/{0024-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch => 0023-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch} (99%) rename paper-server/patches/features/{0025-Incremental-chunk-and-player-saving.patch => 0024-Incremental-chunk-and-player-saving.patch} (97%) rename paper-server/patches/features/{0026-Optimise-general-POI-access.patch => 0025-Optimise-general-POI-access.patch} (100%) rename paper-server/patches/features/{0027-Optional-per-player-mob-spawns.patch => 0026-Optional-per-player-mob-spawns.patch} (99%) rename paper-server/patches/features/{0028-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch => 0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch} (98%) rename paper-server/patches/features/{0029-Optimize-Hoppers.patch => 0028-Optimize-Hoppers.patch} (99%) rename paper-server/patches/features/{0030-Optimise-collision-checking-in-player-move-packet-ha.patch => 0029-Optimise-collision-checking-in-player-move-packet-ha.patch} (99%) diff --git a/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch b/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch deleted file mode 100644 index 2d6d532ce..000000000 --- a/paper-server/patches/features/0009-Fix-entity-type-tags-suggestions-in-selectors.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 22 Aug 2021 15:21:57 -0700 -Subject: [PATCH] Fix entity type tags suggestions in selectors - -This would really be better as a client fix because just to fix it -all EntityArguments have been told to ask the server for completions -when if this was fixed on the client, that wouldn't be needed. - -Mojira Issue: https://bugs.mojang.com/browse/MC-235045 - -diff --git a/net/minecraft/commands/CommandSourceStack.java b/net/minecraft/commands/CommandSourceStack.java -index cf923441da598637be74a5ffa4b4f948e01ff532..cbf32be9235921ebcaca88225120c2ca70a72771 100644 ---- a/net/minecraft/commands/CommandSourceStack.java -+++ b/net/minecraft/commands/CommandSourceStack.java -@@ -676,4 +676,20 @@ public class CommandSourceStack implements ExecutionCommandSource getSelectedEntities() { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && this.source instanceof ServerPlayer player) { -+ final Entity cameraEntity = player.getCamera(); -+ final double pickDistance = player.entityInteractionRange(); -+ final Vec3 min = cameraEntity.getEyePosition(1.0F); -+ final Vec3 viewVector = cameraEntity.getViewVector(1.0F); -+ final Vec3 max = min.add(viewVector.x * pickDistance, viewVector.y * pickDistance, viewVector.z * pickDistance); -+ final net.minecraft.world.phys.AABB aabb = cameraEntity.getBoundingBox().expandTowards(viewVector.scale(pickDistance)).inflate(1.0D, 1.0D, 1.0D); -+ final net.minecraft.world.phys.EntityHitResult hitResult = net.minecraft.world.entity.projectile.ProjectileUtil.getEntityHitResult(cameraEntity, min, max, aabb, (e) -> !e.isSpectator() && e.isPickable(), pickDistance * pickDistance); -+ return hitResult != null ? java.util.Collections.singletonList(hitResult.getEntity().getStringUUID()) : SharedSuggestionProvider.super.getSelectedEntities(); -+ } -+ return SharedSuggestionProvider.super.getSelectedEntities(); -+ } -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - } -diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java -index fa8c5ba4e0efd0c36613aaa8eaafba0cb70ceb87..19ccf3abf14c67f72a1ca065e4a304f50e645ef4 100644 ---- a/net/minecraft/commands/Commands.java -+++ b/net/minecraft/commands/Commands.java -@@ -509,6 +509,7 @@ public class Commands { - Map, CommandNode> commandNodeToSuggestionNode - ) { - commandNodeToSuggestionNode.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains(":")); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below -+ boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments - for (CommandNode commandNode : children) { // Paper - Perf: Async command map building; pass copy of children - // Paper start - Brigadier API - if (commandNode.clientNode != null) { -@@ -572,6 +573,12 @@ public class Commands { - RequiredArgumentBuilder requiredArgumentBuilder = (RequiredArgumentBuilder)argumentBuilder; - if (requiredArgumentBuilder.getSuggestionsProvider() != null) { - requiredArgumentBuilder.suggests(SuggestionProviders.safelySwap(requiredArgumentBuilder.getSuggestionsProvider())); -+ // Paper start - tell clients to ask server for suggestions for EntityArguments -+ registeredAskServerSuggestionsForTree = requiredArgumentBuilder.getSuggestionsProvider() == net.minecraft.commands.synchronization.SuggestionProviders.ASK_SERVER; -+ } else if (io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && !registeredAskServerSuggestionsForTree && requiredArgumentBuilder.getType() instanceof net.minecraft.commands.arguments.EntityArgument) { -+ requiredArgumentBuilder.suggests(requiredArgumentBuilder.getType()::listSuggestions); -+ registeredAskServerSuggestionsForTree = true; // You can only -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - } - } - -diff --git a/net/minecraft/commands/arguments/EntityArgument.java b/net/minecraft/commands/arguments/EntityArgument.java -index 0a01df6ebd14afe79bc76364cb1df5e0c5c08074..77a68052c7653aee54c60f4bded9fa5337e3e4db 100644 ---- a/net/minecraft/commands/arguments/EntityArgument.java -+++ b/net/minecraft/commands/arguments/EntityArgument.java -@@ -138,7 +138,7 @@ public class EntityArgument implements ArgumentType { - final boolean permission = sharedSuggestionProvider instanceof CommandSourceStack stack - ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector") - : sharedSuggestionProvider.hasPermission(2); -- EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission); -+ EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission, true); // Paper - tell clients to ask server for suggestions for EntityArguments - // Paper end - Fix EntityArgument permissions - - try { -diff --git a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java -index a6f232747df631f6afe440606bea94c588f1a0dd..fb42630741674c6cbd20b7d45d78dea1dc73a78f 100644 ---- a/net/minecraft/commands/arguments/selector/EntitySelectorParser.java -+++ b/net/minecraft/commands/arguments/selector/EntitySelectorParser.java -@@ -115,8 +115,15 @@ public class EntitySelectorParser { - private boolean hasScores; - private boolean hasAdvancements; - private boolean usesSelectors; -+ public boolean parsingEntityArgumentSuggestions; // Paper - tell clients to ask server for suggestions for EntityArguments - - public EntitySelectorParser(StringReader reader, boolean allowSelectors) { -+ // Paper start - tell clients to ask server for suggestions for EntityArguments -+ this(reader, allowSelectors, false); -+ } -+ public EntitySelectorParser(StringReader reader, boolean allowSelectors, boolean parsingEntityArgumentSuggestions) { -+ this.parsingEntityArgumentSuggestions = parsingEntityArgumentSuggestions; -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - this.reader = reader; - this.allowSelectors = allowSelectors; - } -diff --git a/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java b/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java -index f6b58139aace70436034f0a16370236d975cb4ae..ee9949c41d38817b21b6f4fd728059a46fddf135 100644 ---- a/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java -+++ b/net/minecraft/commands/arguments/selector/options/EntitySelectorOptions.java -@@ -76,6 +76,19 @@ public class EntitySelectorOptions { - public static final DynamicCommandExceptionType ERROR_ENTITY_TYPE_INVALID = new DynamicCommandExceptionType( - type -> Component.translatableEscape("argument.entity.options.type.invalid", type) - ); -+ // Paper start - tell clients to ask server for suggestions for EntityArguments -+ public static final DynamicCommandExceptionType ERROR_ENTITY_TAG_INVALID = new DynamicCommandExceptionType((object) -> { -+ return io.papermc.paper.adventure.PaperAdventure -+ .asVanilla(net.kyori.adventure.text.Component -+ .text("Invalid or unknown entity type tag '" + object + "'") -+ .hoverEvent(net.kyori.adventure.text.event.HoverEvent -+ .showText(net.kyori.adventure.text.Component -+ .text("You can disable this error in 'paper.yml'") -+ ) -+ ) -+ ); -+ }); -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - - private static void register(String id, EntitySelectorOptions.Modifier handler, Predicate predicate, Component tooltip) { - OPTIONS.put(id, new EntitySelectorOptions.Option(handler, predicate, tooltip)); -@@ -299,6 +312,12 @@ public class EntitySelectorOptions { - - if (parser.isTag()) { - TagKey> tagKey = TagKey.create(Registries.ENTITY_TYPE, ResourceLocation.read(parser.getReader())); -+ // Paper start - tell clients to ask server for suggestions for EntityArguments; throw error if invalid entity tag (only on suggestions to keep cmd success behavior) -+ if (parser.parsingEntityArgumentSuggestions && io.papermc.paper.configuration.GlobalConfiguration.get().commands.fixTargetSelectorTagCompletion && net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.get(tagKey).isEmpty()) { -+ parser.getReader().setCursor(cursor); -+ throw ERROR_ENTITY_TAG_INVALID.createWithContext(parser.getReader(), tagKey); -+ } -+ // Paper end - tell clients to ask server for suggestions for EntityArguments - parser.addPredicate(entity -> entity.getType().is(tagKey) != shouldInvertValue); - } else { - ResourceLocation resourceLocation = ResourceLocation.read(parser.getReader()); diff --git a/paper-server/patches/features/0010-Handle-Oversized-block-entities-in-chunks.patch b/paper-server/patches/features/0009-Handle-Oversized-block-entities-in-chunks.patch similarity index 100% rename from paper-server/patches/features/0010-Handle-Oversized-block-entities-in-chunks.patch rename to paper-server/patches/features/0009-Handle-Oversized-block-entities-in-chunks.patch diff --git a/paper-server/patches/features/0011-optimize-dirt-and-snow-spreading.patch b/paper-server/patches/features/0010-optimize-dirt-and-snow-spreading.patch similarity index 100% rename from paper-server/patches/features/0011-optimize-dirt-and-snow-spreading.patch rename to paper-server/patches/features/0010-optimize-dirt-and-snow-spreading.patch diff --git a/paper-server/patches/features/0012-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/paper-server/patches/features/0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch similarity index 100% rename from paper-server/patches/features/0012-Optimise-getChunkAt-calls-for-loaded-chunks.patch rename to paper-server/patches/features/0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch diff --git a/paper-server/patches/features/0013-Optimize-Bit-Operations-by-inlining.patch b/paper-server/patches/features/0012-Optimize-Bit-Operations-by-inlining.patch similarity index 100% rename from paper-server/patches/features/0013-Optimize-Bit-Operations-by-inlining.patch rename to paper-server/patches/features/0012-Optimize-Bit-Operations-by-inlining.patch diff --git a/paper-server/patches/features/0014-Remove-streams-from-hot-code.patch b/paper-server/patches/features/0013-Remove-streams-from-hot-code.patch similarity index 100% rename from paper-server/patches/features/0014-Remove-streams-from-hot-code.patch rename to paper-server/patches/features/0013-Remove-streams-from-hot-code.patch diff --git a/paper-server/patches/features/0015-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch b/paper-server/patches/features/0014-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch similarity index 100% rename from paper-server/patches/features/0015-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch rename to paper-server/patches/features/0014-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch diff --git a/paper-server/patches/features/0016-Rewrite-dataconverter-system.patch b/paper-server/patches/features/0015-Rewrite-dataconverter-system.patch similarity index 99% rename from paper-server/patches/features/0016-Rewrite-dataconverter-system.patch rename to paper-server/patches/features/0015-Rewrite-dataconverter-system.patch index ef5f7da45..cd20ceb47 100644 --- a/paper-server/patches/features/0016-Rewrite-dataconverter-system.patch +++ b/paper-server/patches/features/0015-Rewrite-dataconverter-system.patch @@ -30621,7 +30621,7 @@ index 1110ca4075a1bbaa46b66686435dab91b275c945..c2218630c3074c8b3f82364e37503b12 return structureTemplate.save(new CompoundTag()); } diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 0d65bf24f515b80701150fdc430f324a533cb478..b92a3da5c325e69f5601416d4205fb33429742b3 100644 +index e54b5a165ad4dc4d2158dab34c5008512e5f7885..841a41485af62470d833aba578069b19a0bd1e8d 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java @@ -305,6 +305,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop Date: Mon, 13 Jan 2025 00:29:52 +0100 Subject: [PATCH 046/203] Call PlayerItemDamageEvent for tridents (#11899) --- .../features/0028-Optimize-Hoppers.patch | 4 +-- .../minecraft/world/item/ItemStack.java.patch | 28 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/features/0028-Optimize-Hoppers.patch b/paper-server/patches/features/0028-Optimize-Hoppers.patch index 0536fe611..3625f8dfc 100644 --- a/paper-server/patches/features/0028-Optimize-Hoppers.patch +++ b/paper-server/patches/features/0028-Optimize-Hoppers.patch @@ -60,10 +60,10 @@ index cc2d442682496197d29ace79b22e6cf6fb7edf5e..ae220a732c78ab076261f20b5a54c71d /* Drop global time updates if (this.tickCount % 20 == 0) { diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index 0eb9811e573f0c38de3eeb17099872efcbb4c2dd..b511fe8295369ac4014beb351cd2e3f770c10170 100644 +index b393be76bead3c66ab0bd8a0e6fd9b9ef81d8e28..76f50437396f8f856381d0fbef52953ef7c263f6 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -808,10 +808,16 @@ public final class ItemStack implements DataComponentHolder { +@@ -827,10 +827,16 @@ public final class ItemStack implements DataComponentHolder { } public ItemStack copy() { diff --git a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch index 297a82f02..e0ed9f76a 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch @@ -292,7 +292,33 @@ this.shrink(1); onBreak.accept(item); } -@@ -512,9 +_,14 @@ +@@ -506,15 +_,39 @@ + return; + } + +- int min = Math.min(this.getDamageValue() + i, this.getMaxDamage() - 1); ++ int min = Math.min(this.getDamageValue() + i, this.getMaxDamage() - 1); // Paper - Expand PlayerItemDamageEvent - diff on change as min computation is copied post event. ++ ++ // Paper start - Expand PlayerItemDamageEvent ++ if (min - this.getDamageValue() > 0) { ++ org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent( ++ serverPlayer.getBukkitEntity(), ++ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), ++ min - this.getDamageValue(), ++ damage ++ ); ++ if (!event.callEvent() || event.getDamage() == 0) { ++ return; ++ } ++ ++ // Prevent breaking the item in this code path as callers may expect the item to survive ++ // (given the method name) ++ min = Math.min(this.getDamageValue() + event.getDamage(), this.getMaxDamage() - 1); ++ } ++ // Paper end - Expand PlayerItemDamageEvent ++ + this.applyDamage(min, serverPlayer, item -> {}); + } } public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) { From 1bb3677651770f274404b2a245c9b51cb82b776a Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Mon, 13 Jan 2025 17:51:58 +0100 Subject: [PATCH 047/203] Remove deprecation from EntityRemoveEvent (#11961) Bukkits entity remove event is called at a different time than the existing paper event, specifically it is called after an entity has been stored during chunk unloads. This means that, while the bukkit event can have a defined reason, it does not allow modification to the entity data. In this regard it differs from the paper implementation and prevents developers from using the paper event as an alternative. Co-authored-by: TonytheMacaroni --- .../java/org/bukkit/event/entity/EntityRemoveEvent.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java index 8ed5d1ccc..2a826175f 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityRemoveEvent.java @@ -1,9 +1,7 @@ package org.bukkit.event.entity; -import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent; import org.bukkit.entity.Entity; import org.bukkit.event.HandlerList; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -12,9 +10,11 @@ import org.jetbrains.annotations.NotNull; * This event should only be used for monitoring. The result * of modifying the entity during or after this event is unspecified. * This event is not called for a {@link org.bukkit.entity.Player}. - * @deprecated use {@link EntityRemoveFromWorldEvent} instead + *

+ * It differs from {@link com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent} as to when it is called. + * Modifications to the entity, as noted above, are not defined and are expected to not be persisted in e.g., chunk + * unloads. */ -@Deprecated(forRemoval = true) public class EntityRemoveEvent extends EntityEvent { private static final HandlerList handlers = new HandlerList(); From d69981b611c8afc67e55aa9955a749e3af119a77 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 13 Jan 2025 13:51:40 -0700 Subject: [PATCH 048/203] [ci skip] Remove redundant build configuration This is already the default path for the reobf mappings patch. --- paper-server/build.gradle.kts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index 9367f2a15..d881e5205 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -21,10 +21,6 @@ paperweight { // macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java") // gitFilePatches = true - paper { - reobfMappingsPatch = layout.projectDirectory.file("../build-data/reobf-mappings-patch.tiny") - } - spigot { buildDataRef = "3edaf46ec1eed4115ce1b18d2846cded42577e42" packageVersion = "v1_21_R3" // also needs to be updated in MappingEnvironment From 6fde26d7f885b208bda543bc7fbd2aa012fdb5c8 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 13 Jan 2025 18:48:51 -0800 Subject: [PATCH 049/203] remove .paperassetsroot No longer needed with new build system --- paper-server/src/main/resources/data/.paperassetsroot | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 paper-server/src/main/resources/data/.paperassetsroot diff --git a/paper-server/src/main/resources/data/.paperassetsroot b/paper-server/src/main/resources/data/.paperassetsroot deleted file mode 100644 index e69de29bb..000000000 From fe75eaf09a22a5cc46877edb714274638d3b111f Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 13 Jan 2025 20:12:13 -0800 Subject: [PATCH 050/203] split direct holder support up from ctor accepting Holder Enchantment shouldn't support direct holders despite the ctor accepting a Holder type. We want to limit the types to ones that are actually used as direct holders in the game --- .../paper/registry/PaperRegistries.java | 12 +++--- .../paper/registry/PaperRegistryAccess.java | 2 +- .../InlinedRegistryBuilderProviderImpl.java | 2 +- .../registry/entry/RegistryEntryBuilder.java | 6 ++- .../registry/entry/RegistryTypeMapper.java | 39 ++++++++++++------- .../io/papermc/paper/util/Holderable.java | 10 ++--- .../craftbukkit/CraftMusicInstrument.java | 2 +- .../org/bukkit/craftbukkit/CraftRegistry.java | 36 +++++------------ .../inventory/trim/CraftTrimMaterial.java | 2 +- .../inventory/trim/CraftTrimPattern.java | 2 +- .../registry/RegistryConversionTest.java | 2 +- .../io/papermc/testplugin/TestPlugin.java | 13 +++++++ 12 files changed, 70 insertions(+), 58 deletions(-) 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 f6e6aeee1..c0b17315a 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 @@ -97,21 +97,21 @@ public final class PaperRegistries { start(Registries.MENU, RegistryKey.MENU).craft(MenuType.class, CraftMenuType::new).build(), start(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE).craft(Attribute.class, CraftAttribute::new).build(), start(Registries.FLUID, RegistryKey.FLUID).craft(Fluid.class, CraftFluid::new).build(), - start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new).build(), + start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new, true).build(), start(Registries.DATA_COMPONENT_TYPE, RegistryKey.DATA_COMPONENT_TYPE).craft(DataComponentTypes.class, PaperDataComponentType::of).build(), // data-drivens start(Registries.BIOME, RegistryKey.BIOME).craft(Biome.class, CraftBiome::new).build().delayed(), start(Registries.STRUCTURE, RegistryKey.STRUCTURE).craft(Structure.class, CraftStructure::new).build().delayed(), - start(Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL).craft(TrimMaterial.class, CraftTrimMaterial::new).build().delayed(), - start(Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN).craft(TrimPattern.class, CraftTrimPattern::new).build().delayed(), + 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.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).writable(PaperBannerPatternRegistryEntry.PaperBuilder::new).delayed(), - start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), - start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::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(), // api-only start(Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE).apiOnly(PaperSimpleRegistry::entityType), diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java index ab8fba344..e96c28cec 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java @@ -107,7 +107,7 @@ public class PaperRegistryAccess implements RegistryAccess { public void lockReferenceHolders(final ResourceKey> resourceKey) { final RegistryEntry entry = PaperRegistries.getEntry(resourceKey); - if (entry == null || !(entry.meta() instanceof final RegistryEntryMeta.ServerSide serverSide) || !serverSide.registryTypeMapper().supportsDirectHolders()) { + if (entry == null || !(entry.meta() instanceof final RegistryEntryMeta.ServerSide serverSide) || !serverSide.registryTypeMapper().constructorUsesHolder()) { return; } final CraftRegistry registry = (CraftRegistry) this.getRegistry(entry.apiKey()); diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java index 8d7d75840..e0d23b3dc 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java @@ -24,7 +24,7 @@ public final class InlinedRegistryBuilderProviderImpl implements InlinedRegistry Preconditions.checkArgument(buildableMeta.registryTypeMapper().supportsDirectHolders(), "Registry type mapper must support direct holders"); final PaperRegistryBuilderFactory builderFactory = new PaperRegistryBuilderFactory<>(Conversions.global(), buildableMeta.builderFiller(), CraftRegistry.getMinecraftRegistry(buildableMeta.mcKey())::getValue); value.accept(builderFactory); - return buildableMeta.registryTypeMapper().convertDirectHolder(Holder.direct(builderFactory.requireBuilder().build())); + return buildableMeta.registryTypeMapper().createBukkit(Holder.direct(builderFactory.requireBuilder().build())); } @Override diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java index bb7d19ee0..57a46cc90 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java @@ -42,7 +42,11 @@ public class RegistryEntryBuilder { // TODO remove Keyed } public CraftStage craft(final Class classToPreload, final Function, ? extends A> minecraftToBukkit) { - return new CraftStage<>(this.mcKey, this.apiKey, classToPreload, new RegistryTypeMapper<>(minecraftToBukkit)); + return this.craft(classToPreload, minecraftToBukkit, false); + } + + public CraftStage craft(final Class classToPreload, final Function, ? extends A> minecraftToBukkit, final boolean allowDirect) { + return new CraftStage<>(this.mcKey, this.apiKey, classToPreload, new RegistryTypeMapper<>(minecraftToBukkit, allowDirect)); } public static final class CraftStage extends RegistryEntryBuilder { // TODO remove Keyed diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryTypeMapper.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryTypeMapper.java index c950524f7..87c0f502a 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryTypeMapper.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryTypeMapper.java @@ -1,7 +1,7 @@ package io.papermc.paper.registry.entry; -import com.google.common.base.Preconditions; import com.mojang.datafixers.util.Either; +import io.papermc.paper.util.MCUtil; import java.util.function.BiFunction; import java.util.function.Function; import net.minecraft.core.Holder; @@ -9,29 +9,40 @@ import org.bukkit.NamespacedKey; public final class RegistryTypeMapper { - final Either, Function, ? extends A>> minecraftToBukkit; + private static Function, ? extends A> wrap(final BiFunction byValueCreator) { + return holder -> { + if (!(holder instanceof final Holder.Reference reference)) { + throw new IllegalArgumentException("This type does not support direct holders: " + holder); + } + return byValueCreator.apply(MCUtil.fromResourceKey(reference.key()), reference.value()); + }; + } + + final Either, ? extends A>, BiFunction> minecraftToBukkit; + private final boolean supportsDirectHolders; public RegistryTypeMapper(final BiFunction byValueCreator) { - this.minecraftToBukkit = Either.left(byValueCreator); + this.minecraftToBukkit = Either.right(byValueCreator); + this.supportsDirectHolders = false; } - public RegistryTypeMapper(final Function, ? extends A> byHolderCreator) { - this.minecraftToBukkit = Either.right(byHolderCreator); + public RegistryTypeMapper(final Function, ? extends A> byHolderCreator, final boolean supportsDirectHolders) { + this.minecraftToBukkit = Either.left(byHolderCreator); + this.supportsDirectHolders = supportsDirectHolders; } - public A createBukkit(final NamespacedKey key, final Holder minecraft) { - return this.minecraftToBukkit.map( - minecraftToBukkit -> minecraftToBukkit.apply(key, minecraft.value()), - minecraftToBukkit -> minecraftToBukkit.apply(minecraft) - ); + public A createBukkit(final Holder minecraft) { + return this.minecraftToBukkit., ? extends A>>map( + Function.identity(), + RegistryTypeMapper::wrap + ).apply(minecraft); } public boolean supportsDirectHolders() { - return this.minecraftToBukkit.right().isPresent(); + return this.supportsDirectHolders; } - public A convertDirectHolder(final Holder directHolder) { - Preconditions.checkArgument(this.supportsDirectHolders() && directHolder.kind() == Holder.Kind.DIRECT); - return this.minecraftToBukkit.right().orElseThrow().apply(directHolder); + public boolean constructorUsesHolder() { + return this.minecraftToBukkit.left().isPresent(); } } diff --git a/paper-server/src/main/java/io/papermc/paper/util/Holderable.java b/paper-server/src/main/java/io/papermc/paper/util/Holderable.java index 5958c6fd4..746c14b17 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/Holderable.java +++ b/paper-server/src/main/java/io/papermc/paper/util/Holderable.java @@ -27,7 +27,7 @@ public interface Holderable extends Handleable { return this.getHolder().value(); } - static @Nullable T fromBukkitSerializationObject(final Object deserialized, final Codec> codec, final RegistryKey registryKey) { // TODO remove Keyed + static @Nullable T fromBukkitSerializationObject(final Object deserialized, final Codec directCodec, final RegistryKey registryKey) { // TODO remove Keyed final Registry registry = RegistryAccess.registryAccess().getRegistry(registryKey); return switch (deserialized) { case @Subst("key:value") final String string -> { @@ -41,18 +41,18 @@ public interface Holderable extends Handleable { throw new IllegalArgumentException("Cannot deserialize direct holders for " + registry); } final RegistryOps ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); - final Holder holder = codec.decode(ops, element).getOrThrow().getFirst(); - yield ((CraftRegistry) registry).convertDirectHolder(holder); + final M holder = directCodec.decode(ops, element).getOrThrow().getFirst(); + yield ((CraftRegistry) registry).createBukkit(Holder.direct(holder)); } default -> throw new IllegalArgumentException("Cannot deserialize " + deserialized); }; } - default Object toBukkitSerializationObject(final Codec> codec) { + default Object toBukkitSerializationObject(final Codec directCodec) { return switch (this.getHolder()) { case final Holder.Direct direct -> { final RegistryOps ops = CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE); - yield new JsonObjectWrapper(codec.encodeStart(ops, direct).getOrThrow().getAsJsonObject()); + yield new JsonObjectWrapper(directCodec.encodeStart(ops, direct.value()).getOrThrow().getAsJsonObject()); } case final Holder.Reference reference -> reference.key().location().toString(); default -> throw new IllegalArgumentException("Cannot serialize " + this.getHolder()); 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 b72a07064..26a93c4f2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftMusicInstrument.java @@ -32,7 +32,7 @@ public class CraftMusicInstrument extends MusicInstrument implements io.papermc. public static Object bukkitToString(MusicInstrument bukkit) { // Paper - switch to Holder Preconditions.checkArgument(bukkit != null); - return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.CODEC); // Paper - switch to Holder + return ((CraftMusicInstrument) bukkit).toBukkitSerializationObject(Instrument.DIRECT_CODEC); // Paper - switch to Holder } public static MusicInstrument stringToBukkit(Object string) { // Paper - switch to Holder diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index fcf177b3c..2de46d741 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -62,7 +62,7 @@ public class CraftRegistry implements Registry { final Registry bukkitRegistry = RegistryAccess.registryAccess().getRegistry(PaperRegistries.registryFromNms(registryKey)); final java.util.Optional> resourceKey = registry.getResourceKey(minecraft); if (resourceKey.isEmpty() && bukkitRegistry instanceof final CraftRegistry craftRegistry && craftRegistry.supportsDirectHolders()) { - return ((CraftRegistry) bukkitRegistry).convertDirectHolder(Holder.direct(minecraft)); + return ((CraftRegistry) bukkitRegistry).createBukkit(Holder.direct(minecraft)); } else if (resourceKey.isEmpty()) { throw new IllegalStateException(String.format("Cannot convert '%s' to bukkit representation, since it is not registered.", minecraft)); } @@ -82,7 +82,7 @@ public class CraftRegistry implements Registry { if (!(bukkitRegistry instanceof final CraftRegistry craftRegistry) || !craftRegistry.supportsDirectHolders()) { throw new IllegalArgumentException("Cannot convert direct holder to bukkit representation"); } - yield ((CraftRegistry) bukkitRegistry).convertDirectHolder(direct); + yield ((CraftRegistry) bukkitRegistry).createBukkit(direct); } case final Holder.Reference reference -> bukkitRegistry.get(MCUtil.fromResourceKey(reference.key())); default -> throw new IllegalArgumentException("Unknown holder: " + minecraft); @@ -126,8 +126,8 @@ public class CraftRegistry implements Registry { // Paper start - fixup upstream being dum public static Optional unwrapAndConvertHolder(final RegistryKey registryKey, final Holder value) { final Registry registry = RegistryAccess.registryAccess().getRegistry(registryKey); - if (registry instanceof CraftRegistry craftRegistry && craftRegistry.supportsDirectHolders() && value.kind() == Holder.Kind.DIRECT) { - return Optional.of(((CraftRegistry) registry).convertDirectHolder(value)); + if (registry instanceof final CraftRegistry craftRegistry && craftRegistry.supportsDirectHolders() && value.kind() == Holder.Kind.DIRECT) { + return Optional.of(((CraftRegistry) registry).createBukkit(value)); } return value.unwrapKey().map(key -> registry.get(CraftNamespacedKey.fromMinecraft(key.location()))); } @@ -178,7 +178,7 @@ public class CraftRegistry implements Registry { this.minecraftRegistry = minecraftRegistry; this.minecraftToBukkit = minecraftToBukkit; this.serializationUpdater = serializationUpdater; - this.lockReferenceHolders = !this.minecraftToBukkit.supportsDirectHolders(); + this.lockReferenceHolders = !this.minecraftToBukkit.constructorUsesHolder(); } public void lockReferenceHolders() { @@ -189,7 +189,7 @@ public class CraftRegistry implements Registry { } catch (final ClassNotFoundException e) { throw new IllegalStateException("Failed to load class " + this.bukkitClass.getSimpleName(), e); } - if (!this.minecraftToBukkit.supportsDirectHolders()) { + if (!this.minecraftToBukkit.constructorUsesHolder()) { return; } Preconditions.checkState(!this.lockReferenceHolders, "Reference holders are already locked"); @@ -209,7 +209,7 @@ public class CraftRegistry implements Registry { final Holder.Reference holder; if (holderOptional.isPresent()) { holder = holderOptional.get(); - } else if (!this.lockReferenceHolders && this.minecraftToBukkit.supportsDirectHolders()) { // only works if its Holderable + } else if (!this.lockReferenceHolders && this.minecraftToBukkit.constructorUsesHolder()) { // only works if its Holderable // we lock the reference holders after the preload class has been initialized // this is to support the vanilla mechanic of preventing vanilla registry entries being loaded. We need // to create something to fill the API constant fields, so we create a dummy reference holder. @@ -217,7 +217,7 @@ public class CraftRegistry implements Registry { } else { holder = null; } - final B bukkit = this.createBukkit(namespacedKey, holder); + final B bukkit = this.createBukkit(holder); if (bukkit == null) { return null; } @@ -227,16 +227,6 @@ public class CraftRegistry implements Registry { return bukkit; } - @NotNull - @Override - public B getOrThrow(@NotNull NamespacedKey namespacedKey) { - B object = this.get(namespacedKey); - - Preconditions.checkArgument(object != null, "No %s registry entry found for key %s.", this.minecraftRegistry.key(), namespacedKey); - - return object; - } - @NotNull @Override public Stream stream() { @@ -248,24 +238,18 @@ public class CraftRegistry implements Registry { return this.stream().iterator(); } - public B createBukkit(NamespacedKey namespacedKey, Holder minecraft) { // Paper - switch to Holder + public B createBukkit(Holder minecraft) { if (minecraft == null) { return null; } - return this.minecraftToBukkit.createBukkit(namespacedKey, minecraft); // Paper - switch to Holder + return this.minecraftToBukkit.createBukkit(minecraft); } - // Paper start - support Direct Holders public boolean supportsDirectHolders() { return this.minecraftToBukkit.supportsDirectHolders(); } - public B convertDirectHolder(Holder holder) { - return this.minecraftToBukkit.convertDirectHolder(holder); - } - // Paper end - support Direct Holders - // Paper start - improve Registry @Override public NamespacedKey getKey(final B value) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java index d4905c329..5595be33b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimMaterial.java @@ -36,7 +36,7 @@ public class CraftTrimMaterial implements TrimMaterial, io.papermc.paper.util.Ho public static Object bukkitToObject(TrimMaterial bukkit) { Preconditions.checkArgument(bukkit != null); - return ((CraftTrimMaterial) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimMaterial.CODEC); // Paper - switch to Holder + return ((CraftTrimMaterial) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimMaterial.DIRECT_CODEC); // Paper - switch to Holder } public static TrimMaterial objectToBukkit(Object object) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java index 3e3c0d3ba..031361c75 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/trim/CraftTrimPattern.java @@ -36,7 +36,7 @@ public class CraftTrimPattern implements TrimPattern, io.papermc.paper.util.Hold public static Object bukkitToObject(TrimPattern bukkit) { Preconditions.checkArgument(bukkit != null); - return ((CraftTrimPattern) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimPattern.CODEC); // Paper - switch to Holder + return ((CraftTrimPattern) bukkit).toBukkitSerializationObject(net.minecraft.world.item.equipment.trim.TrimPattern.DIRECT_CODEC); // Paper - switch to Holder } public static TrimPattern objectToBukkit(Object object) { diff --git a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java index 49b8fdb1a..402773499 100644 --- a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java +++ b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java @@ -263,7 +263,7 @@ public class RegistryConversionTest { Joiner.on('\n').withKeyValueSeparator(" got: ").join(notMatching))); } - static final Set> IGNORE_FOR_DIRECT_HOLDER = Set.of(RegistryKey.TRIM_MATERIAL, RegistryKey.TRIM_PATTERN, RegistryKey.INSTRUMENT, RegistryKey.PAINTING_VARIANT, RegistryKey.BANNER_PATTERN, RegistryKey.SOUND_EVENT, RegistryKey.ENCHANTMENT); // Paper + static final Set> IGNORE_FOR_DIRECT_HOLDER = Set.of(RegistryKey.TRIM_MATERIAL, RegistryKey.TRIM_PATTERN, RegistryKey.INSTRUMENT, RegistryKey.PAINTING_VARIANT, RegistryKey.BANNER_PATTERN, RegistryKey.SOUND_EVENT); // Paper /** * Minecraft registry can return a default key / value diff --git a/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java b/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java index 671c37fa4..d36c60e14 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java @@ -1,5 +1,11 @@ package io.papermc.testplugin; +import io.papermc.paper.event.player.ChatEvent; +import io.papermc.paper.registry.keys.PaintingVariantKeys; +import org.bukkit.Art; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Painting; +import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; @@ -12,4 +18,11 @@ public final class TestPlugin extends JavaPlugin implements Listener { // io.papermc.testplugin.brigtests.Registration.registerViaOnEnable(this); } + @EventHandler + public void onEvent(ChatEvent event) { + final Entity targetEntity = event.getPlayer().getTargetEntity(10); + if (targetEntity instanceof Painting painting) { + painting.setArt(Art.create(f -> f.copyFrom(PaintingVariantKeys.BAROQUE).height(10))); + } + } } From c44f891d99e765b0f6d1f6d026828e34938e7f9e Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:11:20 +0200 Subject: [PATCH 051/203] Fix PlayerUseUnknownEntityEvent jd (#11969) --- .../paper/event/player/PlayerUseUnknownEntityEvent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java index 9ff2bbf7f..99610d0fe 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java @@ -11,7 +11,7 @@ import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; /** - * Represents an event that is called when a player right-clicks an unknown entity. + * Represents an event that is called when a player clicks an unknown entity. * Useful for plugins dealing with virtual entities (entities that aren't actually spawned on the server). *
* This event may be called multiple times per interaction with different interaction hands From 85d0040f57ede2a324ba430fb9edd3bd38484a49 Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:42:34 +0200 Subject: [PATCH 052/203] [ci skip] Fix getTemperature javadocs (#11967) In 1.15 spigot changed the behavior of all temperature methods to always return height adjusted temperature. Correctly reflect this in the javadocs. --- paper-api/src/main/java/org/bukkit/World.java | 6 ------ paper-api/src/main/java/org/bukkit/block/Block.java | 3 --- 2 files changed, 9 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index e5e6cdec5..e99fa923d 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -2593,9 +2593,6 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient *

* It is safe to run this method when the block does not exist, it will * not create the block. - *

- * This method will return the raw temperature without adjusting for block - * height effects. * * @param x X coordinate of the block * @param z Z coordinate of the block @@ -2610,9 +2607,6 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient *

* It is safe to run this method when the block does not exist, it will * not create the block. - *

- * This method will return the raw temperature without adjusting for block - * height effects. * * @param x X coordinate of the block * @param y Y coordinate of the block diff --git a/paper-api/src/main/java/org/bukkit/block/Block.java b/paper-api/src/main/java/org/bukkit/block/Block.java index b7530e7f3..b703ad820 100644 --- a/paper-api/src/main/java/org/bukkit/block/Block.java +++ b/paper-api/src/main/java/org/bukkit/block/Block.java @@ -509,9 +509,6 @@ public interface Block extends Metadatable, Translatable, net.kyori.adventure.tr /** * Gets the temperature of this block. - *

- * If the raw biome temperature without adjusting for height effects is - * required then please use {@link World#getTemperature(int, int, int)}. * * @return Temperature of this block */ From e82f7e6bb6e41a0442212bd1a495800ad33cb5c7 Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Tue, 14 Jan 2025 14:43:28 +0200 Subject: [PATCH 053/203] [ci skip] Fix Inventory#setMaxStackSize jd (#11968) --- paper-api/src/main/java/org/bukkit/inventory/Inventory.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/inventory/Inventory.java b/paper-api/src/main/java/org/bukkit/inventory/Inventory.java index 1cea8361c..dfcb16dfe 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/Inventory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/Inventory.java @@ -48,11 +48,13 @@ public interface Inventory extends Iterable { * Caveats: *

* * @param size The new maximum stack size for items in this inventory. From 9f74858760f8fbb9e8a231dc8c698f1a7855599a Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 14 Jan 2025 14:36:19 +0100 Subject: [PATCH 054/203] [ci skip] Cleanup test plugin --- .../java/io/papermc/testplugin/TestPlugin.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java b/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java index d36c60e14..fd891f5b1 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/TestPlugin.java @@ -1,11 +1,5 @@ package io.papermc.testplugin; -import io.papermc.paper.event.player.ChatEvent; -import io.papermc.paper.registry.keys.PaintingVariantKeys; -import org.bukkit.Art; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Painting; -import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; @@ -17,12 +11,4 @@ public final class TestPlugin extends JavaPlugin implements Listener { // io.papermc.testplugin.brigtests.Registration.registerViaOnEnable(this); } - - @EventHandler - public void onEvent(ChatEvent event) { - final Entity targetEntity = event.getPlayer().getTargetEntity(10); - if (targetEntity instanceof Painting painting) { - painting.setArt(Art.create(f -> f.copyFrom(PaintingVariantKeys.BAROQUE).height(10))); - } - } } From eeec611b9d16cb93ce720a7ab8cbf87f5516d499 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 14 Jan 2025 17:15:47 +0100 Subject: [PATCH 055/203] Fix zombie villager infection chance hunk (#11974) Dropped during hardfork, now moved to a false-ed out if statement to prevent dropping in future updates. --- .../net/minecraft/world/entity/monster/Zombie.java.patch | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch index c3460fb7a..4732375eb 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch @@ -191,7 +191,7 @@ } @Override -@@ -423,12 +_,18 @@ +@@ -423,13 +_,19 @@ if (compound.contains("DrownedConversionTime", 99) && compound.getInt("DrownedConversionTime") > -1) { this.startUnderWaterConversion(compound.getInt("DrownedConversionTime")); } @@ -206,11 +206,13 @@ public boolean killedEntity(ServerLevel level, LivingEntity entity) { boolean flag = super.killedEntity(level, entity); - if ((level.getDifficulty() == Difficulty.NORMAL || level.getDifficulty() == Difficulty.HARD) && entity instanceof Villager villager) { -+ final double fallbackChance = level.getDifficulty() == Difficulty.HARD ? 100 : level.getDifficulty() == Difficulty.NORMAL ? 50 : 0; // Paper - Configurable chance of villager zombie infection +- if (level.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) { ++ final double fallbackChance = level.getDifficulty() == Difficulty.HARD ? 100 : level.getDifficulty() == Difficulty.NORMAL ? 50 : 0; // Paper - Configurable chance of villager zombie infection - moved up from belows if + if (this.random.nextDouble() * 100 < level.paperConfig().entities.behavior.zombieVillagerInfectionChance.or(fallbackChance) && entity instanceof Villager villager) { // Paper - Configurable chance of villager zombie infection - if (level.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) { ++ if (false && level.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) { // Paper - Configurable chance of villager zombie infection - moved to "fallbackChance" return flag; } + @@ -465,7 +_,7 @@ spawnGroupData = super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); float specialMultiplier = difficulty.getSpecialMultiplier(); From 209e5f8580e11016640a3b639a6e4d2d3b4dae0a Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 14 Jan 2025 19:03:30 +0100 Subject: [PATCH 056/203] Readd dropped hunk for ender dragon fight data (#11975) Dragon fight data should be read from the now split world instead of the main world level.dat. Partial hunk was dropped during hardfork. --- .../net/minecraft/server/level/ServerLevel.java.patch | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index acc43a771..12113ed24 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -204,15 +204,17 @@ chunkGenerator, this.chunkSource.randomState(), this, -@@ -281,7 +_,7 @@ +@@ -281,8 +_,8 @@ fixerUpper ); this.structureManager = new StructureManager(this, server.getWorldData().worldGenOptions(), this.structureCheck); - if (this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) { +- this.dragonFight = new EndDragonFight(this, seed, server.getWorldData().endDragonFightData()); + if (this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END - this.dragonFight = new EndDragonFight(this, seed, server.getWorldData().endDragonFightData()); ++ this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit } else { this.dragonFight = null; + } @@ -292,7 +_,15 @@ this.randomSequences = Objects.requireNonNullElseGet( randomSequences, () -> this.getDataStorage().computeIfAbsent(RandomSequences.factory(seed), "random_sequences") From 8e80d4e15852ffbed1a18d1e9b34550191433200 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 14 Jan 2025 19:21:52 +0100 Subject: [PATCH 057/203] Correctly construct StructureManager --- .../net/minecraft/server/level/ServerLevel.java.patch | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 12113ed24..a47985fdc 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -204,12 +204,14 @@ chunkGenerator, this.chunkSource.randomState(), this, -@@ -281,8 +_,8 @@ +@@ -280,9 +_,9 @@ + seed, fixerUpper ); - this.structureManager = new StructureManager(this, server.getWorldData().worldGenOptions(), this.structureCheck); +- this.structureManager = new StructureManager(this, server.getWorldData().worldGenOptions(), this.structureCheck); - if (this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END)) { - this.dragonFight = new EndDragonFight(this, seed, server.getWorldData().endDragonFightData()); ++ this.structureManager = new StructureManager(this, this.serverLevelData.worldGenOptions(), this.structureCheck); // CraftBukkit + if (this.dimension() == Level.END && this.dimensionTypeRegistration().is(BuiltinDimensionTypes.END) || env == org.bukkit.World.Environment.THE_END) { // CraftBukkit - Allow to create EnderDragonBattle in default and custom END + this.dragonFight = new EndDragonFight(this, this.serverLevelData.worldGenOptions().seed(), this.serverLevelData.endDragonFightData()); // CraftBukkit } else { From b6be7cd0ae7a7173eea0dbf0e09c1a32b997268b Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:38:56 -0700 Subject: [PATCH 058/203] [ci skip] Move generated API sources to src/generated/java (#11977) This removes a required patch set for forks. --- paper-api-generator/build.gradle.kts | 2 +- paper-api/build.gradle.kts | 2 +- .../java}/com/destroystokyo/paper/entity/ai/VanillaGoal.java | 0 .../java}/io/papermc/paper/registry/keys/AttributeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/BannerPatternKeys.java | 0 .../java}/io/papermc/paper/registry/keys/BiomeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/BlockTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/CatVariantKeys.java | 0 .../java}/io/papermc/paper/registry/keys/DamageTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/EnchantmentKeys.java | 0 .../java}/io/papermc/paper/registry/keys/FluidKeys.java | 0 .../java}/io/papermc/paper/registry/keys/FrogVariantKeys.java | 0 .../java}/io/papermc/paper/registry/keys/GameEventKeys.java | 0 .../java}/io/papermc/paper/registry/keys/InstrumentKeys.java | 0 .../java}/io/papermc/paper/registry/keys/ItemTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/JukeboxSongKeys.java | 0 .../io/papermc/paper/registry/keys/MapDecorationTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/MenuTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/MobEffectKeys.java | 0 .../io/papermc/paper/registry/keys/PaintingVariantKeys.java | 0 .../java}/io/papermc/paper/registry/keys/SoundEventKeys.java | 0 .../java}/io/papermc/paper/registry/keys/StructureKeys.java | 0 .../java}/io/papermc/paper/registry/keys/StructureTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/TrimMaterialKeys.java | 0 .../java}/io/papermc/paper/registry/keys/TrimPatternKeys.java | 0 .../io/papermc/paper/registry/keys/VillagerProfessionKeys.java | 0 .../java}/io/papermc/paper/registry/keys/VillagerTypeKeys.java | 0 .../java}/io/papermc/paper/registry/keys/WolfVariantKeys.java | 0 .../papermc/paper/registry/keys/tags/BannerPatternTagKeys.java | 0 .../java}/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/CatVariantTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java | 0 .../java}/io/papermc/paper/registry/keys/tags/FluidTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/GameEventTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java | 0 .../paper/registry/keys/tags/PaintingVariantTagKeys.java | 0 .../io/papermc/paper/registry/keys/tags/StructureTagKeys.java | 0 41 files changed, 2 insertions(+), 2 deletions(-) rename {paper-api-generator/generated => paper-api/src/generated/java}/com/destroystokyo/paper/entity/ai/VanillaGoal.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/AttributeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/BannerPatternKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/BiomeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/BlockTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/CatVariantKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/DamageTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/EnchantmentKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/FluidKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/FrogVariantKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/GameEventKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/InstrumentKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/ItemTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/JukeboxSongKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/MenuTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/MobEffectKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/PaintingVariantKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/SoundEventKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/StructureKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/StructureTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/TrimMaterialKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/TrimPatternKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/VillagerProfessionKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/VillagerTypeKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/WolfVariantKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/CatVariantTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/FluidTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java (100%) rename {paper-api-generator/generated => paper-api/src/generated/java}/io/papermc/paper/registry/keys/tags/StructureTagKeys.java (100%) diff --git a/paper-api-generator/build.gradle.kts b/paper-api-generator/build.gradle.kts index 57d1018a9..0eab98b0f 100644 --- a/paper-api-generator/build.gradle.kts +++ b/paper-api-generator/build.gradle.kts @@ -25,7 +25,7 @@ tasks.register("generate") { dependsOn(tasks.check) mainClass.set("io.papermc.generator.Main") classpath(sourceSets.main.map { it.runtimeClasspath }) - args(projectDir.toPath().resolve("generated").toString()) + args(rootProject.layout.projectDirectory.dir("paper-api/src/generated/java").asFile.absolutePath) javaLauncher = javaToolchains.defaultJavaLauncher(project) } diff --git a/paper-api/build.gradle.kts b/paper-api/build.gradle.kts index 8b5d559a9..e86b16b6c 100644 --- a/paper-api/build.gradle.kts +++ b/paper-api/build.gradle.kts @@ -93,7 +93,7 @@ dependencies { testRuntimeOnly("org.junit.platform:junit-platform-launcher") } -val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("paper-api-generator/generated") +val generatedApiPath: java.nio.file.Path = layout.projectDirectory.dir("src/generated/java").asFile.toPath() idea { module { generatedSourceDirs.add(generatedApiPath.toFile()) diff --git a/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/paper-api/src/generated/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java similarity index 100% rename from paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java rename to paper-api/src/generated/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/AttributeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/AttributeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BannerPatternKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/BannerPatternKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/BiomeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/BlockTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/BlockTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/CatVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/CatVariantKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/DamageTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/DamageTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/EnchantmentKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/EnchantmentKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/FluidKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/FluidKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/FrogVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/FrogVariantKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/GameEventKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/InstrumentKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/InstrumentKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/ItemTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/ItemTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/JukeboxSongKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/JukeboxSongKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/MenuTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/MenuTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/MobEffectKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/MobEffectKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/PaintingVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/PaintingVariantKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/SoundEventKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/SoundEventKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/StructureKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/StructureTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/TrimMaterialKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/TrimPatternKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerProfessionKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerProfessionKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/VillagerTypeKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/WolfVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/WolfVariantKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/CatVariantTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/CatVariantTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/CatVariantTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/CatVariantTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/FluidTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/FluidTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/FluidTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/FluidTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java diff --git a/paper-api-generator/generated/io/papermc/paper/registry/keys/tags/StructureTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/StructureTagKeys.java similarity index 100% rename from paper-api-generator/generated/io/papermc/paper/registry/keys/tags/StructureTagKeys.java rename to paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/StructureTagKeys.java From cd9d6d69989e599b38941451580efd5c7a6d62ea Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Wed, 15 Jan 2025 12:13:58 +0100 Subject: [PATCH 059/203] Allow duplicate relative flags in entity teleport Fixes #11976 --- .../main/java/org/bukkit/craftbukkit/entity/CraftEntity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 4562bee2e..6d81a1974 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 @@ -5,6 +5,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; @@ -243,7 +244,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { Preconditions.checkArgument(location != null, "location cannot be null"); location.checkFinite(); // Paper start - Teleport passenger API - Set flagSet = Set.of(flags); + Set flagSet = new HashSet<>(List.of(flags)); // Wrap into list while multiple old flags link to the same new one boolean dismount = !flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE); boolean retainPassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS); // Don't allow teleporting between worlds while keeping passengers From b1b88cd31687c5b3f80c4b0b51fd93a63b3e2498 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Wed, 15 Jan 2025 12:58:10 -0700 Subject: [PATCH 060/203] [ci skip] Update paperweight to 2.0.0-beta.14 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9a7683700..9c20ed02f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ import java.nio.file.Path import kotlin.random.Random plugins { - id("io.papermc.paperweight.core") version "2.0.0-beta.13" apply false + id("io.papermc.paperweight.core") version "2.0.0-beta.14" apply false } subprojects { From 938a84fc39cfe4d443db46a8fa756d5188bfd895 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Fri, 17 Jan 2025 13:46:59 +0000 Subject: [PATCH 061/203] Add missing TagSerializable to GsonDataComponentValue converter (Fixes #11768) --- .../DataComponentValueConverterProviderImpl.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java index ee2076fd0..f0b4083d3 100644 --- a/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java @@ -76,6 +76,20 @@ public class DataComponentValueConverterProviderImpl implements DataComponentVal throw new IllegalArgumentException(e); } } + ), + DataComponentValueConverterRegistry.Conversion.convert( + DataComponentValue.TagSerializable.class, + GsonDataComponentValue.class, + (key, tagSerializable) -> { + Tag decodedSnbt; + try { + decodedSnbt = tagSerializable.asBinaryTag().get(PaperAdventure.NBT_CODEC); + } catch (CommandSyntaxException e) { + throw new IllegalArgumentException("Unable to parse SNBT value", e); + } + + return GsonDataComponentValue.gsonDataComponentValue(NbtOps.INSTANCE.convertTo(JsonOps.INSTANCE, decodedSnbt)); + } ) ); } From e150ffd2724b557f3345d3da47967d6921d766d4 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Fri, 17 Jan 2025 13:49:38 +0000 Subject: [PATCH 062/203] Add missing final "muh checkstyle" more like "muh missing style config" --- .../providers/DataComponentValueConverterProviderImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java index f0b4083d3..cfd146de4 100644 --- a/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/adventure/providers/DataComponentValueConverterProviderImpl.java @@ -84,7 +84,7 @@ public class DataComponentValueConverterProviderImpl implements DataComponentVal Tag decodedSnbt; try { decodedSnbt = tagSerializable.asBinaryTag().get(PaperAdventure.NBT_CODEC); - } catch (CommandSyntaxException e) { + } catch (final CommandSyntaxException e) { throw new IllegalArgumentException("Unable to parse SNBT value", e); } From a35cfe93f9f3686279ac44649783ca5a71475a6a Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Fri, 17 Jan 2025 15:31:45 +0000 Subject: [PATCH 063/203] Correct version of some network related dependencies --- paper-server/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index d881e5205..e24fe4a24 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -137,10 +137,10 @@ dependencies { runtimeOnly(log4jPlugins.output) alsoShade(log4jPlugins.output) - implementation("com.velocitypowered:velocity-native:3.3.0-SNAPSHOT") { + implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") { isTransitive = false } - implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Add support for proxy protocol + implementation("io.netty:netty-codec-haproxy:4.1.115.Final") // Add support for proxy protocol implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1") implementation("org.ow2.asm:asm-commons:9.7.1") implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") From 73f7736eb93a64cc0270929cb01992404696d66d Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sat, 18 Jan 2025 10:30:13 -0300 Subject: [PATCH 064/203] Drop patch for MC-273635 fixed in MC 1.21.4 (#11987) --- .../entity/trialspawner/TrialSpawner.java.patch | 9 --------- .../entity/trialspawner/TrialSpawnerData.java.patch | 12 ------------ .../entity/trialspawner/TrialSpawnerState.java.patch | 11 ----------- 3 files changed, 32 deletions(-) delete mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch index 028fc739b..52a66eabe 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch @@ -36,12 +36,3 @@ for (ItemStack itemStack : randomItems) { DefaultDispenseItemBehavior.spawnItem(level, itemStack, 2, Direction.UP, Vec3.atBottomCenterOf(pos).relative(Direction.UP, 1.2)); } -@@ -362,7 +_,7 @@ - } - - public void overrideEntityToSpawn(EntityType entityType, Level level) { -- this.data.reset(); -+ this.data.reset(this); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - this.normalConfig = Holder.direct(this.normalConfig.value().withSpawning(entityType)); - this.ominousConfig = Holder.direct(this.ominousConfig.value().withSpawning(entityType)); - this.setState(level, TrialSpawnerState.INACTIVE); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch index 351f01f84..b1ff9e67b 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch @@ -1,17 +1,5 @@ --- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java +++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -@@ -101,9 +_,9 @@ - this.ejectingLootTable = ejectingLootTable; - } - -- public void reset() { -+ public void reset(TrialSpawner spawner) { // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - this.currentMobs.clear(); -- this.nextSpawnData = Optional.empty(); -+ if (!spawner.getConfig().spawnPotentialsDefinition().isEmpty()) this.nextSpawnData = Optional.empty(); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - this.resetStatistics(); - } - @@ -206,7 +_,7 @@ mob.dropPreservedEquipment(level); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch deleted file mode 100644 index 28b53c34d..000000000 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java -+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerState.java -@@ -145,7 +_,7 @@ - yield ACTIVE; - } else if (data.isCooldownFinished(level)) { - spawner.removeOminous(level, pos); -- data.reset(); -+ data.reset(spawner); // Paper - Fix TrialSpawner forgets assigned mob; MC-273635 - yield WAITING_FOR_PLAYERS; - } else { - yield this; From 30fdfb1aa173a8362e3a5bf19a4e309341f3ee19 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Mon, 20 Jan 2025 11:47:07 -0300 Subject: [PATCH 065/203] [ci skip] Fix docs for DamageResistant (#11992) --- .../io/papermc/paper/datacomponent/item/DamageResistant.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java index 6cbd73cb2..384098ea5 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/DamageResistant.java @@ -21,9 +21,9 @@ public interface DamageResistant { } /** - * The types that this damage type is invincible tp. + * The types that this damage type is invincible to. * - * @return item + * @return the key of the tag holding the respective damage types. */ @Contract(value = "-> new", pure = true) TagKey types(); From 6b7650d81b0e1ef13280f0e7d9d39788e97e54a4 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 22 Jan 2025 18:20:24 +0100 Subject: [PATCH 066/203] Only add goat horn once (#12001) --- .../net/minecraft/world/entity/animal/goat/Goat.java.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch index af11b98e9..1f19c91cf 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch @@ -25,10 +25,11 @@ this.playEatingSound(); } -@@ -350,7 +_,7 @@ +@@ -349,8 +_,7 @@ + double d1 = Mth.randomBetween(this.random, 0.3F, 0.7F); double d2 = Mth.randomBetween(this.random, -0.2F, 0.2F); ItemEntity itemEntity = new ItemEntity(this.level(), vec3.x(), vec3.y(), vec3.z(), itemStack, d, d1, d2); - this.level().addFreshEntity(itemEntity); +- this.level().addFreshEntity(itemEntity); - return true; + return this.spawnAtLocation((net.minecraft.server.level.ServerLevel) this.level(), itemEntity) != null; // Paper - Call EntityDropItemEvent } From 30046e041049e4a942ba5367dba1b1aaaf1ba91e Mon Sep 17 00:00:00 2001 From: TomTom <93038247+AverageGithub@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:58:44 +0100 Subject: [PATCH 067/203] Fix a rare crash with a concurrent modification of scaled health attributes (#12002) --- .../java/org/bukkit/craftbukkit/entity/CraftPlayer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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 98fc89cc7..f80f89a79 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 @@ -24,6 +24,7 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -2858,9 +2859,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { if (!this.scaledHealth && !force) { return; } - for (AttributeInstance genericInstance : collection) { + Iterator iterator = collection.iterator(); + while (iterator.hasNext()) { + AttributeInstance genericInstance = iterator.next(); if (genericInstance.getAttribute() == Attributes.MAX_HEALTH) { - collection.remove(genericInstance); + iterator.remove(); break; } } From 88bbead13b07914c01866e35df16b72110fa501e Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 20 Jan 2025 13:34:10 -0800 Subject: [PATCH 068/203] Flush regionfiles on save configuration option The windows file system does not write metadata unless the FileChannel is explicitly flushed with metaData=true. Note: Setting SYNC (not DSYNC) on the FileChannel does not appear to write the metadata. Specifically, we are interested in writing the last modified timestamp so that fs watchers can detect when RegionFiles are modified. --- ...onfiles-on-save-configuration-option.patch | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 paper-server/patches/features/0030-Flush-regionfiles-on-save-configuration-option.patch diff --git a/paper-server/patches/features/0030-Flush-regionfiles-on-save-configuration-option.patch b/paper-server/patches/features/0030-Flush-regionfiles-on-save-configuration-option.patch new file mode 100644 index 000000000..d7b455d7e --- /dev/null +++ b/paper-server/patches/features/0030-Flush-regionfiles-on-save-configuration-option.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 20 Jan 2025 13:30:34 -0800 +Subject: [PATCH] Flush regionfiles on save configuration option + +The windows file system does not write metadata unless +the FileChannel is explicitly flushed with metaData=true. + +Note: Setting SYNC (not DSYNC) on the FileChannel does not appear +to write the metadata. + +Specifically, we are interested in writing the last modified +timestamp so that fs watchers can detect when RegionFiles are +modified. + +diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +index 1acea58838f057ab87efd103cbecb6f5aeaef393..98fbc5c8044bd945d64569f13412a6e7e49a4e7f 100644 +--- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +@@ -1258,6 +1258,14 @@ public final class MoonriseRegionFileIO { + + try { + this.regionDataController.finishWrite(this.chunkX, this.chunkZ, writeData); ++ // Paper start - flush regionfiles on save ++ if (this.world.paperConfig().chunks.flushRegionsOnSave) { ++ final RegionFile regionFile = this.regionDataController.getCache().moonrise$getRegionFileIfLoaded(this.chunkX, this.chunkZ); ++ if (regionFile != null) { ++ regionFile.flush(); ++ } // else: evicted from cache, which should have called flush ++ } ++ // Paper end - flush regionfiles on save + } catch (final Throwable thr) { + failedWrite = thr instanceof IOException; + LOGGER.error("Failed to write chunk data for task: " + this.toString(), thr); From 336ea9dfeb23d9eae0711db974a3465dfe72746f Mon Sep 17 00:00:00 2001 From: Creeam <102713261+HaHaWTH@users.noreply.github.com> Date: Sat, 25 Jan 2025 11:04:47 -0800 Subject: [PATCH 069/203] Check for empty when sending equipment changes (#12008) --- paper-api/src/main/java/org/bukkit/entity/Player.java | 2 +- .../main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) 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 7d21ee64c..f563cf486 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Player.java +++ b/paper-api/src/main/java/org/bukkit/entity/Player.java @@ -1063,7 +1063,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param entity the entity whose equipment to change * @param items the slots to change, where the values are the items to which - * the slot should be changed. null values will set the slot to air + * the slot should be changed. null values will set the slot to air, empty map is not allowed */ public void sendEquipmentChange(@NotNull LivingEntity entity, @NotNull Map items); 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 f80f89a79..47d6e61bd 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 @@ -1161,6 +1161,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { 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"); if (this.getHandle().connection == null) { return; From 939bb7828fd9c815b0f406efb03e95e2d065a736 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sat, 25 Jan 2025 20:58:16 +0100 Subject: [PATCH 070/203] Add RayTraceConfigurationBuilder (#11907) --- ...ositionedRayTraceConfigurationBuilder.java | 112 ++++++++++++++++++ .../paper/raytracing/RayTraceTarget.java | 9 ++ paper-api/src/main/java/org/bukkit/World.java | 15 +++ ...ionedRayTraceConfigurationBuilderImpl.java | 90 ++++++++++++++ .../org/bukkit/craftbukkit/CraftWorld.java | 23 ++++ 5 files changed, 249 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilder.java create mode 100644 paper-api/src/main/java/io/papermc/paper/raytracing/RayTraceTarget.java create mode 100644 paper-server/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilderImpl.java diff --git a/paper-api/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilder.java b/paper-api/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilder.java new file mode 100644 index 000000000..9d41e5622 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilder.java @@ -0,0 +1,112 @@ +package io.papermc.paper.raytracing; + +import java.util.function.Predicate; +import org.bukkit.FluidCollisionMode; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.util.Vector; +import org.checkerframework.checker.index.qual.NonNegative; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.NullMarked; + +/** + * A builder for configuring a raytrace with a starting location + * and direction. + */ +@NullMarked +public interface PositionedRayTraceConfigurationBuilder { + + /** + * Sets the starting location. + * + * @param start the new starting location + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder start(Location start); + + /** + * Sets the direction. + * + * @param direction the new direction + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder direction(Vector direction); + + /** + * Sets the maximum distance. + * + * @param maxDistance the new maxDistance + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder maxDistance(@NonNegative double maxDistance); + + /** + * Sets the FluidCollisionMode when looking for block collisions. + *

+ * If collisions with passable blocks are ignored, fluid collisions are + * ignored as well regardless of the fluid collision mode. + * + * @param fluidCollisionMode the new FluidCollisionMode + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder fluidCollisionMode(FluidCollisionMode fluidCollisionMode); + + /** + * Sets whether the raytrace should ignore passable blocks when looking for + * block collisions. + *

+ * If collisions with passable blocks are ignored, fluid collisions are + * ignored as well regardless of the fluid collision mode. + *

+ * Portal blocks are only considered passable if the ray starts within them. + * Apart from that collisions with portal blocks will be considered even if + * collisions with passable blocks are otherwise ignored. + * + * @param ignorePassableBlocks if the raytrace should ignore passable blocks + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder ignorePassableBlocks(boolean ignorePassableBlocks); + + /** + * Sets the size of the raytrace when looking for entity collisions. + * + * @param raySize the new raytrace size + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder raySize(@NonNegative double raySize); + + /** + * Sets the current entity filter when looking for entity collisions. + * + * @param entityFilter predicate for entities the ray can potentially collide with + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder entityFilter(Predicate entityFilter); + + /** + * Sets the current block filter when looking for block collisions. + * + * @param blockFilter predicate for blocks the ray can potentially collide with + * @return a reference to this object + */ + @Contract(value = "_ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder blockFilter(Predicate blockFilter); + + /** + * Sets the targets for the rayTrace. + * + * @param first the first target + * @param others the other targets + * @return a reference to this object + */ + @Contract(value = "_, _ -> this", mutates = "this") + PositionedRayTraceConfigurationBuilder targets(RayTraceTarget first, RayTraceTarget... others); +} diff --git a/paper-api/src/main/java/io/papermc/paper/raytracing/RayTraceTarget.java b/paper-api/src/main/java/io/papermc/paper/raytracing/RayTraceTarget.java new file mode 100644 index 000000000..19820201c --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/raytracing/RayTraceTarget.java @@ -0,0 +1,9 @@ +package io.papermc.paper.raytracing; + +/** + * List of Targets a builder can target. + */ +public enum RayTraceTarget { + ENTITY, + BLOCK +} diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index e99fa923d..8784842d1 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -1,6 +1,7 @@ package org.bukkit; import java.io.File; +import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilder; import org.bukkit.generator.ChunkGenerator; import java.util.ArrayList; @@ -1938,6 +1939,20 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient @Nullable RayTraceResult rayTrace(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter, @Nullable Predicate canCollide); // Paper end + /** + * Performs a ray trace that checks for collisions with the specified + * targets. + *

+ * This may cause loading of chunks! Some implementations may impose + * artificial restrictions on the maximum distance. + * + * @param builderConsumer a consumer to configure the ray trace configuration. + * The received builder is not valid for use outside the consumer + * @return the closest ray trace hit result with either a block or an + * entity, or null if there is no hit + */ + @Nullable RayTraceResult rayTrace(@NotNull Consumer builderConsumer); + /** * Gets the default spawn {@link Location} of this world * diff --git a/paper-server/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilderImpl.java b/paper-server/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilderImpl.java new file mode 100644 index 000000000..3d078858d --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/raytracing/PositionedRayTraceConfigurationBuilderImpl.java @@ -0,0 +1,90 @@ +package io.papermc.paper.raytracing; + +import com.google.common.base.Preconditions; +import java.util.EnumSet; +import java.util.OptionalDouble; +import java.util.function.Predicate; +import org.bukkit.FluidCollisionMode; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.util.Vector; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@NullMarked +public class PositionedRayTraceConfigurationBuilderImpl implements PositionedRayTraceConfigurationBuilder { + + public @Nullable Location start; + public @Nullable Vector direction; + public OptionalDouble maxDistance = OptionalDouble.empty(); + public FluidCollisionMode fluidCollisionMode = FluidCollisionMode.NEVER; + public boolean ignorePassableBlocks; + public double raySize = 0.0D; + public @Nullable Predicate entityFilter; + public @Nullable Predicate blockFilter; + public EnumSet targets = EnumSet.noneOf(RayTraceTarget.class); + + @Override + public PositionedRayTraceConfigurationBuilder start(final Location start) { + Preconditions.checkArgument(start != null, "start must not be null"); + this.start = start.clone(); + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder direction(final Vector direction) { + Preconditions.checkArgument(direction != null, "direction must not be null"); + this.direction = direction.clone(); + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder maxDistance(final double maxDistance) { + Preconditions.checkArgument(maxDistance >= 0, "maxDistance must be non-negative"); + this.maxDistance = OptionalDouble.of(maxDistance); + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder fluidCollisionMode(final FluidCollisionMode fluidCollisionMode) { + Preconditions.checkArgument(fluidCollisionMode != null, "fluidCollisionMode must not be null"); + this.fluidCollisionMode = fluidCollisionMode; + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder ignorePassableBlocks(final boolean ignorePassableBlocks) { + this.ignorePassableBlocks = ignorePassableBlocks; + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder raySize(final double raySize) { + Preconditions.checkArgument(raySize >= 0, "raySize must be non-negative"); + this.raySize = raySize; + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder entityFilter(final Predicate entityFilter) { + Preconditions.checkArgument(entityFilter != null, "entityFilter must not be null"); + this.entityFilter = entityFilter; + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder blockFilter(final Predicate blockFilter) { + Preconditions.checkArgument(blockFilter != null, "blockFilter must not be null"); + this.blockFilter = blockFilter; + return this; + } + + @Override + public PositionedRayTraceConfigurationBuilder targets(final RayTraceTarget first, final RayTraceTarget... others) { + Preconditions.checkArgument(first != null, "first must not be null"); + Preconditions.checkArgument(others != null, "others must not be null"); + this.targets = EnumSet.of(first, others); + return this; + } +} 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 ba32db69c..20f709a4e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -6,9 +6,12 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.mojang.datafixers.util.Pair; import io.papermc.paper.FeatureHooks; +import io.papermc.paper.raytracing.RayTraceTarget; import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilder; +import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilderImpl; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import java.io.File; import java.util.ArrayList; @@ -1248,6 +1251,26 @@ public class CraftWorld extends CraftRegionAccessor implements World { return blockHit; } + @Override + public RayTraceResult rayTrace(Consumer builderConsumer) { + PositionedRayTraceConfigurationBuilderImpl builder = new PositionedRayTraceConfigurationBuilderImpl(); + + builderConsumer.accept(builder); + Preconditions.checkArgument(builder.start != null, "Start location cannot be null"); + Preconditions.checkArgument(builder.direction != null, "Direction vector cannot be null"); + Preconditions.checkArgument(builder.maxDistance.isPresent(), "Max distance must be set"); + Preconditions.checkArgument(!builder.targets.isEmpty(), "At least one target"); + + final double maxDistance = builder.maxDistance.getAsDouble(); + if (builder.targets.contains(RayTraceTarget.ENTITY)) { + if (builder.targets.contains(RayTraceTarget.BLOCK)) { + return this.rayTrace(builder.start, builder.direction, maxDistance, builder.fluidCollisionMode, builder.ignorePassableBlocks, builder.raySize, builder.entityFilter, builder.blockFilter); + } + return this.rayTraceEntities(builder.start, builder.direction, maxDistance, builder.raySize, builder.entityFilter); + } + return this.rayTraceBlocks(builder.start, builder.direction, maxDistance, builder.fluidCollisionMode, builder.ignorePassableBlocks, builder.blockFilter); + } + @Override public List getPlayers() { List list = new ArrayList(this.world.players().size()); From 81bb82f521e91ffc83505e9574bb0deba66f9120 Mon Sep 17 00:00:00 2001 From: Creeam <102713261+HaHaWTH@users.noreply.github.com> Date: Sat, 25 Jan 2025 12:13:21 -0800 Subject: [PATCH 071/203] Fix wrong piston world border check (#12007) --- .../world/level/block/piston/PistonBaseBlock.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch index 8f8179f69..bf7c9d9fe 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonBaseBlock.java.patch @@ -61,6 +61,15 @@ } level.playSound(null, pos, SoundEvents.PISTON_CONTRACT, SoundSource.BLOCKS, 0.5F, level.random.nextFloat() * 0.15F + 0.6F); +@@ -249,7 +_,7 @@ + } + + public static boolean isPushable(BlockState state, Level level, BlockPos pos, Direction movementDirection, boolean allowDestroy, Direction pistonFacing) { +- if (pos.getY() < level.getMinY() || pos.getY() > level.getMaxY() || !level.getWorldBorder().isWithinBounds(pos)) { ++ if (pos.getY() < level.getMinY() || pos.getY() > level.getMaxY() || !level.getWorldBorder().isWithinBounds(pos) || !level.getWorldBorder().isWithinBounds(pos.relative(movementDirection))) { // Paper - Fix piston world border check + return false; + } else if (state.isAir()) { + return true; @@ -305,12 +_,54 @@ BlockState[] blockStates = new BlockState[toPush.size() + toDestroy.size()]; Direction direction = extending ? facing : facing.getOpposite(); From ce95b5d653b7fa497c8dab2a2021f8fac8270854 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sat, 25 Jan 2025 21:33:47 +0100 Subject: [PATCH 072/203] Use proper default for setting null display background color (#12010) --- .../java/org/bukkit/craftbukkit/entity/CraftTextDisplay.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 9ef939b76..3dd5009a9 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 @@ -58,13 +58,13 @@ public class CraftTextDisplay extends CraftDisplay implements TextDisplay { public Color getBackgroundColor() { int color = this.getHandle().getBackgroundColor(); - return (color == -1) ? null : Color.fromARGB(color); + return color == Display.TextDisplay.INITIAL_BACKGROUND ? null : Color.fromARGB(color); } @Override public void setBackgroundColor(Color color) { if (color == null) { - this.getHandle().getEntityData().set(Display.TextDisplay.DATA_BACKGROUND_COLOR_ID, -1); + this.getHandle().getEntityData().set(Display.TextDisplay.DATA_BACKGROUND_COLOR_ID, Display.TextDisplay.INITIAL_BACKGROUND); } else { this.getHandle().getEntityData().set(Display.TextDisplay.DATA_BACKGROUND_COLOR_ID, color.asARGB()); } From 2477f1f6a9ae1f42f2744a2f6cb0daaacf562996 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sat, 25 Jan 2025 17:39:25 -0300 Subject: [PATCH 073/203] [ci skip] fix and improvements for docs in ConsumeEffect component (#11998) --- .../item/consumable/ConsumeEffect.java | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java index 87537e431..8442532a1 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumeEffect.java @@ -21,7 +21,7 @@ public interface ConsumeEffect { * Creates a consume effect that randomly teleports the entity on consumption. * * @param diameter diameter of random teleportation - * @return the effect + * @return the effect instance */ @Contract(value = "_ -> new", pure = true) static TeleportRandomly teleportRandomlyEffect(final float diameter) { @@ -29,21 +29,21 @@ public interface ConsumeEffect { } /** - * Creates a consume effect that gives status effects on consumption. + * Creates a consume effect that removes status effects on consumption. * - * @param key the sound effect to play - * @return the effect + * @param effects the potion effects to remove + * @return the effect instance */ @Contract(value = "_ -> new", pure = true) - static RemoveStatusEffects removeEffects(final RegistryKeySet key) { - return ConsumableTypesBridge.bridge().removeStatusEffects(key); + static RemoveStatusEffects removeEffects(final RegistryKeySet effects) { + return ConsumableTypesBridge.bridge().removeStatusEffects(effects); } /** * Creates a consume effect that plays a sound on consumption. * - * @param key the sound effect to play - * @return the effect + * @param key the key sound effect to play + * @return the effect instance */ @Contract(value = "_ -> new", pure = true) static PlaySound playSoundConsumeEffect(final Key key) { @@ -53,7 +53,7 @@ public interface ConsumeEffect { /** * Creates a consume effect that clears all status effects. * - * @return effect instance + * @return the effect instance */ @Contract(value = "-> new", pure = true) static ClearAllStatusEffects clearAllStatusEffects() { @@ -61,17 +61,20 @@ public interface ConsumeEffect { } /** - * Creates a consume effect that gives status effects on consumption. + * Creates a consume effect that gives potion effects on consumption. * * @param effects the potion effects to apply - * @param probability the probability of these effects being applied, between 0 and 1 inclusive. - * @return the effect + * @param probability the probability of these effects being applied, between 0 and 1 inclusive + * @return the effect instance */ @Contract(value = "_, _ -> new", pure = true) static ApplyStatusEffects applyStatusEffects(final List effects, final float probability) { return ConsumableTypesBridge.bridge().applyStatusEffects(effects, probability); } + /** + * Represents a consumable effect that randomly teleports the entity on consumption. + */ @ApiStatus.Experimental @ApiStatus.NonExtendable interface TeleportRandomly extends ConsumeEffect { @@ -85,14 +88,14 @@ public interface ConsumeEffect { } /** - * Represents a consumable effect that removes status effects on consumption + * Represents a consumable effect that removes status effects on consumption. */ @ApiStatus.Experimental @ApiStatus.NonExtendable interface RemoveStatusEffects extends ConsumeEffect { /** - * Potion effects to remove + * Potion effects to remove. * * @return effects */ @@ -107,7 +110,7 @@ public interface ConsumeEffect { interface PlaySound extends ConsumeEffect { /** - * Sound effect to play in the world + * Sound effect to play in the world. * * @return sound effect */ @@ -124,16 +127,16 @@ public interface ConsumeEffect { } /** - * Represents a consumable effect that applies effects based on a probability on consumption. + * Represents a consumable effect that applies potion effects based on a probability on consumption. */ @ApiStatus.Experimental @ApiStatus.NonExtendable interface ApplyStatusEffects extends ConsumeEffect { /** - * Effect instances to grant + * Potion effect instances to grant. * - * @return effect + * @return potion effects */ List effects(); From fb5b173c6a742c584413c8fc8b7c871d79234756 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Sat, 25 Jan 2025 21:47:08 +0100 Subject: [PATCH 074/203] Add PlayerClientLoadedWorldEvent (#11940) --- .../player/PlayerClientLoadedWorldEvent.java | 46 +++++++++++++++++++ ...on-checking-in-player-move-packet-ha.patch | 10 ++-- .../ServerGamePacketListenerImpl.java.patch | 15 +++++- .../world/entity/player/Player.java.patch | 22 +++++++++ 4 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/player/PlayerClientLoadedWorldEvent.java diff --git a/paper-api/src/main/java/io/papermc/paper/event/player/PlayerClientLoadedWorldEvent.java b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerClientLoadedWorldEvent.java new file mode 100644 index 000000000..1b97997ee --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/player/PlayerClientLoadedWorldEvent.java @@ -0,0 +1,46 @@ +package io.papermc.paper.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a player is marked as loaded. + *

+ * This either happens when the player notifies the server after loading the world (closing the downloading terrain screen) + * or when the player has not done so for 60 ticks after joining the server or respawning. + */ +@NullMarked +public class PlayerClientLoadedWorldEvent extends PlayerEvent { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final boolean timeout; + + @ApiStatus.Internal + public PlayerClientLoadedWorldEvent(final Player who, final boolean timeout) { + super(who); + this.timeout = timeout; + } + + /** + * True if the event was triggered because the server has not been notified by the player + * for 60 ticks after the player joined the server or respawned. + * + * @return true if the event was triggered because of a timeout + */ + public boolean isTimeout() { + return timeout; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} 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 77a7a836d..00cdbd326 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 @@ -88,7 +88,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 } @Override -@@ -1361,7 +1393,7 @@ public class ServerGamePacketListenerImpl +@@ -1368,7 +1400,7 @@ public class ServerGamePacketListenerImpl } } @@ -97,7 +97,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 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 -@@ -1400,6 +1432,7 @@ public class ServerGamePacketListenerImpl +@@ -1407,6 +1439,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 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1432,7 +1465,17 @@ public class ServerGamePacketListenerImpl +@@ -1439,7 +1472,17 @@ public class ServerGamePacketListenerImpl } // Paper start - Add fail move event @@ -124,7 +124,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 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); -@@ -1568,7 +1611,7 @@ public class ServerGamePacketListenerImpl +@@ -1575,7 +1618,7 @@ public class ServerGamePacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -133,7 +133,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 this.awaitingTeleportTime = this.tickCount; this.teleport( this.awaitingPositionFromClient.x, -@@ -1587,6 +1630,33 @@ public class ServerGamePacketListenerImpl +@@ -1594,6 +1637,33 @@ public class ServerGamePacketListenerImpl } } 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 7b1d2a2d2..e485e7c21 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 @@ -373,7 +373,7 @@ this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, -@@ -495,6 +_,7 @@ +@@ -495,12 +_,20 @@ this.lastGoodZ = this.awaitingPositionFromClient.z; this.player.hasChangedDimension(); this.awaitingPositionFromClient = null; @@ -381,6 +381,19 @@ } } + @Override + public void handleAcceptPlayerLoad(ServerboundPlayerLoadedPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); ++ // Paper start - PlayerLoadedWorldEvent ++ if (this.player.hasClientLoaded()) { ++ return; ++ } ++ final io.papermc.paper.event.player.PlayerClientLoadedWorldEvent event = new io.papermc.paper.event.player.PlayerClientLoadedWorldEvent(this.player.getBukkitEntity(), false); ++ event.callEvent(); ++ // Paper end - PlayerLoadedWorldEvent + this.player.setClientLoaded(true); + } + @@ -521,6 +_,7 @@ @Override public void handleRecipeBookChangeSettingsPacket(ServerboundRecipeBookChangeSettingsPacket packet) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch index 83e1b14b2..5e8dba7c7 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -674,3 +674,25 @@ for (int i = 0; i < this.inventory.getContainerSize(); i++) { ItemStack item = this.inventory.getItem(i); +@@ -2089,12 +_,20 @@ + } + + public boolean hasClientLoaded() { +- return this.clientLoaded || this.clientLoadedTimeoutTimer <= 0; ++ return this.clientLoaded; // Paper - Add PlayerLoadedWorldEvent + } + + public void tickClientLoadTimeout() { + if (!this.clientLoaded) { + this.clientLoadedTimeoutTimer--; ++ // Paper start - Add PlayerLoadedWorldEvent ++ if (this.clientLoadedTimeoutTimer <= 0) { ++ this.clientLoaded = true; ++ ++ final io.papermc.paper.event.player.PlayerClientLoadedWorldEvent event = new io.papermc.paper.event.player.PlayerClientLoadedWorldEvent((org.bukkit.craftbukkit.entity.CraftPlayer) getBukkitEntity(), true); ++ event.callEvent(); ++ } ++ // Paper end - Add PlayerLoadedWorldEvent + } + } + From 3af5e77132f88392594de977a882af94ebdb0d41 Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Sun, 26 Jan 2025 22:19:00 +0200 Subject: [PATCH 075/203] Add Player#give (#11995) --- .../paper/entity/PlayerGiveResult.java | 39 +++++++++++++++++++ .../main/java/org/bukkit/entity/Player.java | 36 +++++++++++++++++ .../paper/entity/PaperPlayerGiveResult.java | 20 ++++++++++ .../craftbukkit/entity/CraftPlayer.java | 36 +++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/entity/PlayerGiveResult.java create mode 100644 paper-server/src/main/java/io/papermc/paper/entity/PaperPlayerGiveResult.java diff --git a/paper-api/src/main/java/io/papermc/paper/entity/PlayerGiveResult.java b/paper-api/src/main/java/io/papermc/paper/entity/PlayerGiveResult.java new file mode 100644 index 000000000..cf6a9706e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/entity/PlayerGiveResult.java @@ -0,0 +1,39 @@ +package io.papermc.paper.entity; + +import java.util.Collection; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; + +/** + * A result type used by {@link org.bukkit.entity.Player#give(ItemStack...)} and its overloads. + */ +@NullMarked +public interface PlayerGiveResult { + + /** + * A collection of itemstacks that were not added to the player's inventory as they did not fit. + * The collection is derived from the collections of items to add by creating copies of each stack that was not + * fully added to the inventory and assigning the non-added count as their amount. + *

+ * Itemstacks found here *may* also be found as item entities in the {@link #drops()} collection, as the + * give logic may have dropped them. + * + * @return the unmodifiable collection of itemstacks that are leftover as they could not be added. Each element is a + * copy of the input stack they are derived from. + */ + @Unmodifiable + Collection leftovers(); + + /** + * A collection of item entities dropped as a result of this call to {@link org.bukkit.entity.Player#give(ItemStack...)}. + * The item entities contained here are not guaranteed to match the {@link #leftovers()} as plugins may cancel the + * spawning of item entities. + * + * @return the unmodifiable collection of dropped item entities. + */ + @Unmodifiable + Collection drops(); + +} 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 f563cf486..dd0438516 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Player.java +++ b/paper-api/src/main/java/org/bukkit/entity/Player.java @@ -6,10 +6,12 @@ import java.time.Duration; import java.time.Instant; import java.util.Collection; import java.util.Date; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; import io.papermc.paper.entity.LookAnchor; +import io.papermc.paper.entity.PlayerGiveResult; import org.bukkit.BanEntry; import org.bukkit.DyeColor; import org.bukkit.Effect; @@ -3892,4 +3894,38 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ void sendEntityEffect(org.bukkit.@NotNull EntityEffect effect, @NotNull Entity target); // Paper end - entity effect API + + /** + * Gives the player the items following full vanilla logic, + * making the player drop the items that did not fit into + * the inventory. + * + * @param items the items to give. + * @return the result of this method, holding leftovers and spawned items. + */ + default @NotNull PlayerGiveResult give(@NotNull final ItemStack @NotNull ... items) { + return this.give(List.of(items)); + } + + /** + * Gives the player those items following full vanilla logic, + * making the player drop the items that did not fit into + * the inventory. + * + * @param items the items to give + * @return the result of this method, holding leftovers and spawned items. + */ + default @NotNull PlayerGiveResult give(@NotNull final Collection<@NotNull ItemStack> items) { + return this.give(items, true); + } + + /** + * Gives the player those items following full vanilla logic. + * + * @param items the items to give + * @param dropIfFull whether the player should drop items that + * did not fit the inventory + * @return the result of this method, holding leftovers and spawned items. + */ + @NotNull PlayerGiveResult give(@NotNull Collection<@NotNull ItemStack> items, boolean dropIfFull); } diff --git a/paper-server/src/main/java/io/papermc/paper/entity/PaperPlayerGiveResult.java b/paper-server/src/main/java/io/papermc/paper/entity/PaperPlayerGiveResult.java new file mode 100644 index 000000000..199c58718 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/entity/PaperPlayerGiveResult.java @@ -0,0 +1,20 @@ +package io.papermc.paper.entity; + +import java.util.Collection; +import java.util.Collections; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public record PaperPlayerGiveResult( + @Unmodifiable Collection leftovers, + @Unmodifiable Collection drops +) implements PlayerGiveResult { + + public static final PlayerGiveResult EMPTY = new PaperPlayerGiveResult( + Collections.emptyList(), Collections.emptyList() + ); + +} 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 47d6e61bd..baffa0360 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 @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.io.BaseEncoding; import com.mojang.authlib.GameProfile; @@ -8,6 +9,8 @@ import com.mojang.datafixers.util.Pair; import io.netty.buffer.Unpooled; import io.papermc.paper.FeatureHooks; import io.papermc.paper.entity.LookAnchor; +import io.papermc.paper.entity.PaperPlayerGiveResult; +import io.papermc.paper.entity.PlayerGiveResult; import it.unimi.dsi.fastutil.shorts.ShortArraySet; import it.unimi.dsi.fastutil.shorts.ShortSet; import java.io.ByteArrayOutputStream; @@ -101,6 +104,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeMap; import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.food.FoodData; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.level.GameType; @@ -176,6 +180,7 @@ import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.EnderPearl; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerExpCooldownChangeEvent; @@ -3545,4 +3550,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundEntityEventPacket(((CraftEntity) target).getHandle(), effect.getData())); } // Paper end - entity effect API + + @Override + public @NotNull PlayerGiveResult give(@NotNull final Collection<@NotNull 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. + + // Validate all items before attempting to spawn any. + for (final ItemStack item : items) { + Preconditions.checkArgument(item != null, "ItemStack cannot be null"); + Preconditions.checkArgument(!item.isEmpty(), "ItemStack cannot be empty"); + Preconditions.checkArgument(item.getAmount() <= item.getMaxStackSize(), "ItemStack amount cannot be greater than its max stack size"); + } + + final ServerPlayer handle = this.getHandle(); + final ImmutableList.Builder drops = ImmutableList.builder(); + final ImmutableList.Builder leftovers = ImmutableList.builder(); + for (final ItemStack item : items) { + final net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(item); + final boolean added = handle.getInventory().add(nmsStack); + if (added && nmsStack.isEmpty()) continue; // Item was fully added, neither a drop nor a leftover is needed. + + leftovers.add(CraftItemStack.asBukkitCopy(nmsStack)); // Insert copy to avoid mutation to the dropped item from affecting leftovers + if (!dropIfFull) continue; + + final ItemEntity entity = handle.drop(nmsStack, false, true, false); + if (entity != null) drops.add((Item) entity.getBukkitEntity()); + } + + handle.containerMenu.broadcastChanges(); + return new PaperPlayerGiveResult(leftovers.build(), drops.build()); + } } From 7e21cb818132116efc5305777eb6d72f07431294 Mon Sep 17 00:00:00 2001 From: caramel Date: Mon, 27 Jan 2025 07:00:32 +0900 Subject: [PATCH 076/203] fix PlayerChangedMainHandEvent javadoc (#12020) * fix PlayerChangedMainHandEvent javadoc * Obsolete --------- Co-authored-by: Bjarne Koll --- .../player/PlayerChangedMainHandEvent.java | 26 ++++++++++++++++--- .../server/level/ServerPlayer.java.patch | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerChangedMainHandEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerChangedMainHandEvent.java index 6070b1323..4cd9b6e40 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerChangedMainHandEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerChangedMainHandEvent.java @@ -1,22 +1,26 @@ package org.bukkit.event.player; +import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.inventory.MainHand; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** * Called when a player changes their main hand in the client settings. + * @apiNote Obsolete and replaced by {@link PlayerClientOptionsChangeEvent}. */ +@ApiStatus.Obsolete public class PlayerChangedMainHandEvent extends PlayerEvent { private static final HandlerList handlers = new HandlerList(); // - private final MainHand mainHand; + private final MainHand newMainHand; - public PlayerChangedMainHandEvent(@NotNull Player who, @NotNull MainHand mainHand) { + public PlayerChangedMainHandEvent(@NotNull Player who, @NotNull MainHand newMainHand) { super(who); - this.mainHand = mainHand; + this.newMainHand = newMainHand; } /** @@ -24,10 +28,24 @@ public class PlayerChangedMainHandEvent extends PlayerEvent { * available via {@link Player#getMainHand()}. * * @return the new {@link MainHand} of the player + * @deprecated has never been functional since its implementation and simply returns the old main hand. + * The method is left in this broken state to not break compatibility with plugins that relied on this fact. + * Use {@link #getNewMainHand()} instead or migrate to {@link PlayerClientOptionsChangeEvent#getMainHand()}. */ @NotNull + @Deprecated(since = "1.21.4", forRemoval = true) public MainHand getMainHand() { - return mainHand; + return newMainHand == MainHand.LEFT ? MainHand.RIGHT : MainHand.LEFT; + } + + /** + * Gets the new main hand of the player. + * + * @return the new {@link MainHand} of the player + */ + @NotNull + public MainHand getNewMainHand() { + return newMainHand; } @NotNull 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 bfb5d7cd0..ebf5fb8da 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 @@ -1213,7 +1213,7 @@ + if (this.getMainArm() != clientInformation.mainHand()) { + org.bukkit.event.player.PlayerChangedMainHandEvent event = new org.bukkit.event.player.PlayerChangedMainHandEvent( + this.getBukkitEntity(), -+ this.getMainArm() == HumanoidArm.LEFT ? org.bukkit.inventory.MainHand.LEFT : org.bukkit.inventory.MainHand.RIGHT ++ clientInformation.mainHand() == HumanoidArm.LEFT ? org.bukkit.inventory.MainHand.LEFT : org.bukkit.inventory.MainHand.RIGHT + ); + this.server.server.getPluginManager().callEvent(event); + } From 5a34bf0425f39d7b206a2c7de3bae860740a9da1 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 27 Jan 2025 13:45:44 -0800 Subject: [PATCH 077/203] Correctly retrun true for empty input shapes in EntityGetter#isUnobstructed Vanilla will return true for empty shapes, so we should as well. --- .../0016-Moonrise-optimisation-patches.patch | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index a36ba5d51..0e08e374e 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -26735,7 +26735,7 @@ index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7d if (!passengers.equals(this.lastPassengers)) { this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 192977dd661ee795ada13db895db770293e9b402..95a4e37a3c93f9b3c56c7a7376ed521cd46fbb6f 100644 +index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c639223f09 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -170,7 +170,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; @@ -27496,7 +27496,7 @@ index 192977dd661ee795ada13db895db770293e9b402..95a4e37a3c93f9b3c56c7a7376ed521c } diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 472693a7d10dc67b116db02e3e4472adbc5a4d62..422db52e8a0a08350542670bfc9ba94ad9481d0c 100644 +index f054ea710108e5017bc48fdda5f180a04f5b55e2..f44600604a7bf68c990cd74a1ac2d7900ff6e88e 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team; @@ -29379,7 +29379,7 @@ index 9f34fc4278860dd7bcfa1fd79b15e588b0cc3973..a7ebd624652cb6f0edc735bf6b9760e7 public ClipContext(Vec3 from, Vec3 to, ClipContext.Block block, ClipContext.Fluid fluid, Entity entity) { diff --git a/net/minecraft/world/level/EntityGetter.java b/net/minecraft/world/level/EntityGetter.java -index 300f3ed58109219d97846082941b860585f66fed..e81195df621159da67136f020fa7a6d39d1ee5ed 100644 +index 300f3ed58109219d97846082941b860585f66fed..892a7c1eb1b321ca6d5ca709142e7feae1220815 100644 --- a/net/minecraft/world/level/EntityGetter.java +++ b/net/minecraft/world/level/EntityGetter.java @@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.BooleanOp; @@ -29397,14 +29397,6 @@ index 300f3ed58109219d97846082941b860585f66fed..e81195df621159da67136f020fa7a6d3 - default boolean isUnobstructed(@Nullable Entity entity, VoxelShape shape) { - if (shape.isEmpty()) { -- return true; -- } else { -- for (Entity entity1 : this.getEntities(entity, shape.bounds())) { -- if (!entity1.isRemoved() -- && entity1.blocksBuilding -- && (entity == null || !entity1.isPassengerOfSameVehicle(entity)) -- && Shapes.joinIsNotEmpty(shape, Shapes.create(entity1.getBoundingBox()), BooleanOp.AND)) { -- return false; + // Paper start - rewrite chunk system + @Override + default List moonrise$getHardCollidingEntities(final Entity entity, final AABB box, final Predicate predicate) { @@ -29415,7 +29407,14 @@ index 300f3ed58109219d97846082941b860585f66fed..e81195df621159da67136f020fa7a6d3 + // Paper start - optimise collisions + default boolean isUnobstructed(@Nullable Entity entity, VoxelShape voxel) { + if (voxel.isEmpty()) { -+ return false; + return true; +- } else { +- for (Entity entity1 : this.getEntities(entity, shape.bounds())) { +- if (!entity1.isRemoved() +- && entity1.blocksBuilding +- && (entity == null || !entity1.isPassengerOfSameVehicle(entity)) +- && Shapes.joinIsNotEmpty(shape, Shapes.create(entity1.getBoundingBox()), BooleanOp.AND)) { +- return false; + } + + final AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)voxel).moonrise$getSingleAABBRepresentation(); @@ -29503,7 +29502,7 @@ index 300f3ed58109219d97846082941b860585f66fed..e81195df621159da67136f020fa7a6d3 // Paper start - Affects Spawning API diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 771d6ed6a7c889c09efd4ff6e20298c851eaa79f..8331b49185500ab3b4307e9ae05126b4f83a318a 100644 +index 771d6ed6a7c889c09efd4ff6e20298c851eaa79f..a768f041fd16d253ec4ab5eb75288b1771d5cb00 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -79,6 +79,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -29673,7 +29672,7 @@ index 771d6ed6a7c889c09efd4ff6e20298c851eaa79f..8331b49185500ab3b4307e9ae05126b4 + public boolean isUnobstructed(final Entity entity) { + final AABB boundingBox = entity.getBoundingBox(); + if (ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.isEmpty(boundingBox)) { -+ return false; ++ return true; + } + + final List entities = this.getEntities( From a392d475c28c62f25992de49d5d137b098e4ad92 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 27 Jan 2025 16:25:02 -0800 Subject: [PATCH 078/203] Make Watchdog thread extend TickThread This allows the watchdog thread to be seen as the primary thread during shutdown, which prevents it from tripping thread checks in various areas. Fixes https://github.com/PaperMC/Paper/issues/12030 --- paper-server/src/main/java/org/spigotmc/WatchdogThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java index a9339f59f..dced8899b 100644 --- a/paper-server/src/main/java/org/spigotmc/WatchdogThread.java +++ b/paper-server/src/main/java/org/spigotmc/WatchdogThread.java @@ -11,7 +11,7 @@ import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.CraftServer; -public class WatchdogThread extends Thread { +public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThread { // Paper - rewrite chunk system public static final boolean DISABLE_WATCHDOG = Boolean.getBoolean("disable.watchdog"); // Paper - Improved watchdog support private static WatchdogThread instance; From 1004374a83efcc730876d41b80288359c993ae0e Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 28 Jan 2025 13:28:37 -0800 Subject: [PATCH 079/203] Add further information to thread check errors The entity data is more complete, which will help debug problems on Folia. --- .../0016-Moonrise-optimisation-patches.patch | 50 +++++++++++++++++++ .../moonrise/common/util/TickThread.java | 34 +++++++------ 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 0e08e374e..1d0295204 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -35961,3 +35961,53 @@ index 5b6bd88a5bbbce6cce351938418eba4326e41002..faf45ac459f7c25309d6ef6dce371d48 int i = -this.pendingTicks.size(); for (SavedTick savedTick : this.pendingTicks) { +diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..db5805298d33fbde3f3ed23d706dbc6af814122d +--- /dev/null ++++ b/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java +@@ -0,0 +1,44 @@ ++package ca.spottedleaf.moonrise.common.util; ++ ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.phys.Vec3; ++import java.text.DecimalFormat; ++import java.util.ArrayList; ++import java.util.List; ++ ++public final class EntityUtil { ++ ++ private static final ThreadLocal THREE_DECIMAL_PLACES = ThreadLocal.withInitial(() -> { ++ return new DecimalFormat("#,##0.000"); ++ }); ++ ++ private static String formatVec(final Vec3 vec) { ++ final DecimalFormat format = THREE_DECIMAL_PLACES.get(); ++ ++ return "(" + format.format(vec.x) + "," + format.format(vec.y) + "," + format.format(vec.z) + ")"; ++ } ++ ++ private static String dumpEntityWithoutReferences(final Entity entity) { ++ if (entity == null) { ++ return "{null}"; ++ } ++ ++ return "{type=" + entity.getClass().getSimpleName() + ",id=" + entity.getId() + ",uuid=" + entity.getUUID() + ",pos=" + formatVec(entity.position()) ++ + ",mot=" + formatVec(entity.getDeltaMovement()) + ",aabb=" + entity.getBoundingBox() + ",removed=" + entity.getRemovalReason() + ",has_vehicle=" + (entity.getVehicle() != null) ++ + ",passenger_count=" + entity.getPassengers().size(); ++ } ++ ++ public static String dumpEntity(final Entity entity) { ++ final List passengers = entity.getPassengers(); ++ final List passengerStrings = new ArrayList<>(passengers.size()); ++ ++ for (final Entity passenger : passengers) { ++ passengerStrings.add("(" + dumpEntityWithoutReferences(passenger) + ")"); ++ } ++ ++ return "{root=[" + dumpEntityWithoutReferences(entity) + "], vehicle=[" + dumpEntityWithoutReferences(entity.getVehicle()) ++ + "], passengers=[" + String.join(",", passengerStrings) + "]"; ++ } ++ ++ private EntityUtil() {} ++} diff --git a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java index 157e5edb5..69cdd304d 100644 --- a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java +++ b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/TickThread.java @@ -15,21 +15,25 @@ public class TickThread extends Thread { private static final Logger LOGGER = LoggerFactory.getLogger(TickThread.class); + private static String getThreadContext() { + return "thread=" + Thread.currentThread().getName(); + } + /** * @deprecated */ @Deprecated public static void ensureTickThread(final String reason) { if (!isTickThread()) { - LOGGER.error("Thread " + Thread.currentThread().getName() + " failed main thread check: " + reason, new Throwable()); + LOGGER.error("Thread failed main thread check: " + reason + ", context=" + getThreadContext(), new Throwable()); throw new IllegalStateException(reason); } } public static void ensureTickThread(final Level world, final BlockPos pos, final String reason) { if (!isTickThreadFor(world, pos)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos; + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos; LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } @@ -37,8 +41,8 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final BlockPos pos, final int blockRadius, final String reason) { if (!isTickThreadFor(world, pos, blockRadius)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius; + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + pos + ", block_radius=" + blockRadius; LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } @@ -46,8 +50,8 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final ChunkPos pos, final String reason) { if (!isTickThreadFor(world, pos)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos; + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + pos; LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } @@ -55,8 +59,8 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final int chunkX, final int chunkZ, final String reason) { if (!isTickThreadFor(world, chunkX, chunkZ)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ); + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", chunk_pos=" + new ChunkPos(chunkX, chunkZ); LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } @@ -64,8 +68,8 @@ public class TickThread extends Thread { public static void ensureTickThread(final Entity entity, final String reason) { if (!isTickThreadFor(entity)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", entity=" + entity; + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", entity=" + EntityUtil.dumpEntity(entity); LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } @@ -73,8 +77,8 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final AABB aabb, final String reason) { if (!isTickThreadFor(world, aabb)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb; + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", aabb=" + aabb; LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } @@ -82,8 +86,8 @@ public class TickThread extends Thread { public static void ensureTickThread(final Level world, final double blockX, final double blockZ, final String reason) { if (!isTickThreadFor(world, blockX, blockZ)) { - final String ex = "Thread " + Thread.currentThread().getName() + " failed main thread check: " + - reason + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ); + final String ex = "Thread failed main thread check: " + + reason + ", context=" + getThreadContext() + ", world=" + WorldUtil.getWorldName(world) + ", block_pos=" + new Vec3(blockX, 0.0, blockZ); LOGGER.error(ex, new Throwable()); throw new IllegalStateException(ex); } From e2f0efd1af7d3d22ee7ec2d964d2c553d44a6baf Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 28 Jan 2025 17:25:26 -0800 Subject: [PATCH 080/203] Remove nms.Entity#isChunkLoaded This method was used pre 1.17 era where an Entity was explicitly tied to a (then called) Chunk's entity slices. If an entity was not inside a Chunk, then it was considered invalid as it was not possible to save the entity. In 1.17+, entities are now tied to a separately tracked entity section management system. This system is far more reliable now as it no longer requires a full chunk load to properly track entities for saving. As a result, an Entity if inside the world is always attached to some entity chunk section (except in rare cases in Vanilla which are fixed in Moonrise). As a result, whether the chunk the entity is in is loaded is no longer an indication of whether they are tracked in the world and we can reliably infer that the entity is correctly in the world through the valid field alone. Additionally drop the isInWorld() check, as valid=true implies isInWorld=true. More importantly, the isInWorld() check invokes getHandle which may trip a thread check on Folia. This will fix World#getEntities() and friends exploding on Folia. However, World#getEntities() on Folia still cannot reliably return all entities in the world as actions such as cross-region (not cross-world) teleporting will remove entities from the world. --- .../0003-Entity-Activation-Range-2.0.patch | 10 +++++----- .../0016-Moonrise-optimisation-patches.patch | 20 +++++++++---------- .../minecraft/world/entity/Entity.java.patch | 6 +----- .../org/bukkit/craftbukkit/CraftWorld.java | 4 ++-- .../craftbukkit/entity/CraftEntity.java | 2 +- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch index cbfc717b3..dcb46b821 100644 --- a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch @@ -366,7 +366,7 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f import org.slf4j.Logger; diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 3164f3784131babf9a6663335517a12df7e88a7b..da8848e2a3e3745949eb2356a049451d30f763a7 100644 +index 79d23c3403efc6dbef2381a3fa5946023f862452..3b19229427d83290bba1431bee5357e2ced34f94 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -476,7 +476,7 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index e7889c9c7b155db46730f5e168bb7fd3d1732a8c..334859c5ff7023c730513301cc11c9837b2c7823 100644 +index bf5f2b753e3cbe3dfa8ad86df06718fbc1fbcbc4..988e5740b86c7768fee7391dc7e2900305a51be9 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -380,6 +380,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -495,7 +495,7 @@ index e7889c9c7b155db46730f5e168bb7fd3d1732a8c..334859c5ff7023c730513301cc11c983 public void setOrigin(@javax.annotation.Nonnull org.bukkit.Location location) { this.origin = location.toVector(); -@@ -417,6 +426,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -413,6 +422,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -509,7 +509,7 @@ index e7889c9c7b155db46730f5e168bb7fd3d1732a8c..334859c5ff7023c730513301cc11c983 SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this); builder.define(DATA_SHARED_FLAGS_ID, (byte)0); builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply()); -@@ -981,6 +997,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -977,6 +993,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } else { this.wasOnFire = this.isOnFire(); if (type == MoverType.PISTON) { @@ -518,7 +518,7 @@ index e7889c9c7b155db46730f5e168bb7fd3d1732a8c..334859c5ff7023c730513301cc11c983 movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -994,6 +1012,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -990,6 +1008,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 1d0295204..de786f06e 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -28372,7 +28372,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 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8240e85e7 100644 +index 55e0bd63a65867f4e496ec0b188ccba7a4a8ebef..161c7a53427917fdbd328401a84a7cab703701a8 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -28466,7 +28466,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 } // Paper end - Share random for entities to make them more random public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason -@@ -419,6 +375,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -415,6 +371,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -28623,7 +28623,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 public Entity(EntityType entityType, Level level) { this.type = entityType; -@@ -1327,35 +1433,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1323,35 +1429,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return distance; } @@ -28725,7 +28725,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 } private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { -@@ -2662,23 +2810,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2658,23 +2806,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -28849,7 +28849,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4102,15 +4337,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4098,15 +4333,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -28875,7 +28875,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 } public int countPlayerPassengers() { -@@ -4248,77 +4485,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4244,77 +4481,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(partialTick, this.yRotO, this.yRot); } @@ -29066,7 +29066,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 public boolean touchingUnloadedChunk() { AABB aabb = this.getBoundingBox().inflate(1.0); -@@ -4471,6 +4767,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4467,6 +4763,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29082,7 +29082,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 if (!checkPosition(this, x, y, z)) { return; } -@@ -4601,6 +4906,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4597,6 +4902,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { @@ -29095,7 +29095,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4612,7 +4923,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4608,7 +4919,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29104,7 +29104,7 @@ index 8d7c1ee6c1cd4419621b11029eb06bf8135e59aa..1d0151a042ed5de4e235ef0bdac1a0e8 this.levelCallback.onRemove(removalReason); this.onRemoval(removalReason); // Paper start - Folia schedulers -@@ -4646,7 +4957,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4642,7 +4953,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() 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 780a51d40..d4f61b665 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 @@ -127,7 +127,7 @@ private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0}; private long pistonDeltasGameTime; private EntityDimensions dimensions; -@@ -250,6 +_,63 @@ +@@ -250,6 +_,59 @@ private final List movementThisTick = new ArrayList<>(); private final Set blocksInside = new ReferenceArraySet<>(); private final LongSet visitedBlocks = new LongOpenHashSet(); @@ -178,10 +178,6 @@ + public float getBukkitYaw() { + return this.yRot; + } -+ -+ public boolean isChunkLoaded() { -+ return this.level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); -+ } + // CraftBukkit end + // Paper start + public final AABB getBoundingBoxAt(double x, double y, double z) { 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 20f709a4e..e5fe32d17 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -209,8 +209,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getEntityCount() { int ret = 0; - for (net.minecraft.world.entity.Entity entity : world.getEntities().getAll()) { - if (entity.isChunkLoaded()) { + for (net.minecraft.world.entity.Entity entity : this.world.getEntities().getAll()) { + if (entity.getBukkitEntity().isValid()) { ++ret; } } 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 6d81a1974..659f0f9c7 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 @@ -414,7 +414,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public boolean isValid() { - return this.entity.isAlive() && this.entity.valid && this.entity.isChunkLoaded() && this.isInWorld(); + return this.entity.isAlive() && this.entity.valid; } @Override From 54b2e9d9738ce32e2f415c321f20e3fc07063c14 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Tue, 28 Jan 2025 17:43:30 -0800 Subject: [PATCH 081/203] Add buffer to CraftWorld#warnUnsafeChunk This allows plugins to access chunks slightly outside of the max world border (such as ones which may be loaded naturally by players) without tripping any logs. --- .../src/main/java/org/bukkit/craftbukkit/CraftWorld.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 e5fe32d17..284b58ece 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -356,7 +356,8 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Paper start private static void warnUnsafeChunk(String reason, int x, int z) { // if any chunk coord is outside of 30 million blocks - if (x > 1875000 || z > 1875000 || x < -1875000 || z < -1875000) { + int max = (30_000_000 / 16) + 625; + if (x > max || z > max || x < -max || z < -max) { Plugin plugin = io.papermc.paper.util.StackWalkerUtil.getFirstPluginCaller(); if (plugin != null) { plugin.getLogger().warning("Plugin is %s at (%s, %s), this might cause issues.".formatted(reason, x, z)); From d4a957849c05a5cfcc3d85a2a25adb5ddbfe1181 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:02:14 +0100 Subject: [PATCH 082/203] Experimental annotation changes (#12028) --- .editorconfig | 24 +++++++++---------- CONTRIBUTING.md | 3 ++- .../src/main/java/org/bukkit/Registry.java | 1 - .../main/java/org/bukkit/block/Crafter.java | 3 --- .../java/org/bukkit/block/CreakingHeart.java | 3 --- .../java/org/bukkit/block/TrialSpawner.java | 1 - .../src/main/java/org/bukkit/block/Vault.java | 2 -- .../bukkit/block/data/type/CreakingHeart.java | 2 -- .../bukkit/block/data/type/HangingMoss.java | 2 -- .../bukkit/block/data/type/MossyCarpet.java | 2 -- .../org/bukkit/entity/AbstractWindCharge.java | 2 -- .../main/java/org/bukkit/entity/Bogged.java | 2 -- .../main/java/org/bukkit/entity/Breeze.java | 2 -- .../org/bukkit/entity/BreezeWindCharge.java | 2 -- .../main/java/org/bukkit/entity/Creaking.java | 3 --- .../org/bukkit/entity/OminousItemSpawner.java | 1 - .../java/org/bukkit/entity/WindCharge.java | 2 -- .../org/bukkit/entity/boat/PaleOakBoat.java | 4 +--- .../bukkit/entity/boat/PaleOakChestBoat.java | 4 +--- .../bukkit/inventory/CrafterInventory.java | 2 -- .../org/bukkit/inventory/meta/BundleMeta.java | 2 -- .../server/players/PlayerList.java.patch | 2 +- .../world/level/block/CocoaBlock.java.patch | 2 +- .../data/PaperEnchantmentRegistryEntry.java | 3 --- .../craftbukkit/util/CraftMagicNumbers.java | 2 +- 25 files changed, 19 insertions(+), 59 deletions(-) diff --git a/.editorconfig b/.editorconfig index 65898b518..76c44f065 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,32 +1,32 @@ [*] -charset=utf-8 -end_of_line=lf -insert_final_newline=true -indent_style=space -indent_size=4 +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 ij_any_block_comment_add_space = false ij_any_block_comment_at_first_column = false ij_any_line_comment_at_first_column = false ij_any_line_comment_add_space = true [*.tiny] -indent_style=tab +indent_style = tab [*.bat] -end_of_line=crlf +end_of_line = crlf [*.yml] -indent_size=2 +indent_size = 2 [*.patch] -trim_trailing_whitespace=false +trim_trailing_whitespace = false [*.java] ij_continuation_indent_size = 4 ij_java_class_count_to_use_import_on_demand = 999999 ij_java_insert_inner_class_imports = false ij_java_names_count_to_use_import_on_demand = 999999 -ij_java_imports_layout = *,|,$* +ij_java_imports_layout = *, |, $* ij_java_generate_final_locals = true ij_java_generate_final_parameters = true ij_java_method_parameters_new_line_after_left_paren = true @@ -40,5 +40,5 @@ ij_java_use_fq_class_names = true [paper-server/src/minecraft/resources/data/**/*.json] indent_size = 2 -[paper-api-generator/generated/**/*.java] -ij_java_imports_layout = $*,|,* +[paper-api/src/generated/java/**/*.java] +ij_java_imports_layout = $*, |, * diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c4c275a7f..7805b0fba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -208,7 +208,8 @@ required. with `// Paper end - `. - One-line changes should have `// Paper - ` at the end of the line. -> [!NOTE] These comments are incredibly important to be able to keep track of changes +> [!NOTE] +> These comments are incredibly important to be able to keep track of changes > across files and to remember what they are for, even a decade into the future. Here's an example of how to mark changes by Paper: diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index 50eea2967..8f96e193c 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -271,7 +271,6 @@ public interface Registry extends Iterable { * @see JukeboxSong * @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#JUKEBOX_SONG} */ - @ApiStatus.Experimental @Deprecated(since = "1.21") Registry JUKEBOX_SONG = legacyRegistryFor(JukeboxSong.class); /** diff --git a/paper-api/src/main/java/org/bukkit/block/Crafter.java b/paper-api/src/main/java/org/bukkit/block/Crafter.java index f737a2aae..42244aa28 100644 --- a/paper-api/src/main/java/org/bukkit/block/Crafter.java +++ b/paper-api/src/main/java/org/bukkit/block/Crafter.java @@ -1,8 +1,5 @@ package org.bukkit.block; -import org.bukkit.loot.Lootable; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a captured state of a crafter. */ diff --git a/paper-api/src/main/java/org/bukkit/block/CreakingHeart.java b/paper-api/src/main/java/org/bukkit/block/CreakingHeart.java index 0b60d38f7..f7648e5b2 100644 --- a/paper-api/src/main/java/org/bukkit/block/CreakingHeart.java +++ b/paper-api/src/main/java/org/bukkit/block/CreakingHeart.java @@ -1,10 +1,7 @@ package org.bukkit.block; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a captured state of a creaking heart. */ -@ApiStatus.Experimental public interface CreakingHeart extends TileState { } diff --git a/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java b/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java index 6fc7b5fe1..6c1e3b5f3 100644 --- a/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java +++ b/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java @@ -4,7 +4,6 @@ import java.util.Collection; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.spawner.TrialSpawnerConfiguration; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** diff --git a/paper-api/src/main/java/org/bukkit/block/Vault.java b/paper-api/src/main/java/org/bukkit/block/Vault.java index 375f41fe4..64c7b432c 100644 --- a/paper-api/src/main/java/org/bukkit/block/Vault.java +++ b/paper-api/src/main/java/org/bukkit/block/Vault.java @@ -1,7 +1,5 @@ package org.bukkit.block; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a captured state of a trial spawner. */ diff --git a/paper-api/src/main/java/org/bukkit/block/data/type/CreakingHeart.java b/paper-api/src/main/java/org/bukkit/block/data/type/CreakingHeart.java index aadd902f3..42302837f 100644 --- a/paper-api/src/main/java/org/bukkit/block/data/type/CreakingHeart.java +++ b/paper-api/src/main/java/org/bukkit/block/data/type/CreakingHeart.java @@ -1,14 +1,12 @@ package org.bukkit.block.data.type; import org.bukkit.block.data.Orientable; -import org.jetbrains.annotations.ApiStatus; /** * 'active' is whether the block is active. *
* 'natural' is whether this is a naturally generated block. */ -@ApiStatus.Experimental public interface CreakingHeart extends Orientable { /** diff --git a/paper-api/src/main/java/org/bukkit/block/data/type/HangingMoss.java b/paper-api/src/main/java/org/bukkit/block/data/type/HangingMoss.java index a7f295409..08ecd62cc 100644 --- a/paper-api/src/main/java/org/bukkit/block/data/type/HangingMoss.java +++ b/paper-api/src/main/java/org/bukkit/block/data/type/HangingMoss.java @@ -1,12 +1,10 @@ package org.bukkit.block.data.type; import org.bukkit.block.data.BlockData; -import org.jetbrains.annotations.ApiStatus; /** * 'tip' indicates whether this block is a tip. */ -@ApiStatus.Experimental public interface HangingMoss extends BlockData { /** diff --git a/paper-api/src/main/java/org/bukkit/block/data/type/MossyCarpet.java b/paper-api/src/main/java/org/bukkit/block/data/type/MossyCarpet.java index dd8264faa..1c904b440 100644 --- a/paper-api/src/main/java/org/bukkit/block/data/type/MossyCarpet.java +++ b/paper-api/src/main/java/org/bukkit/block/data/type/MossyCarpet.java @@ -2,7 +2,6 @@ package org.bukkit.block.data.type; import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -11,7 +10,6 @@ import org.jetbrains.annotations.NotNull; * * 'bottom' denotes whether this is a bottom block. */ -@ApiStatus.Experimental public interface MossyCarpet extends BlockData { /** diff --git a/paper-api/src/main/java/org/bukkit/entity/AbstractWindCharge.java b/paper-api/src/main/java/org/bukkit/entity/AbstractWindCharge.java index ecff691c3..ee8017139 100644 --- a/paper-api/src/main/java/org/bukkit/entity/AbstractWindCharge.java +++ b/paper-api/src/main/java/org/bukkit/entity/AbstractWindCharge.java @@ -1,7 +1,5 @@ package org.bukkit.entity; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a Wind Charge. */ diff --git a/paper-api/src/main/java/org/bukkit/entity/Bogged.java b/paper-api/src/main/java/org/bukkit/entity/Bogged.java index c84ddf808..e6e10ad15 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Bogged.java +++ b/paper-api/src/main/java/org/bukkit/entity/Bogged.java @@ -1,7 +1,5 @@ package org.bukkit.entity; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a Bogged Skeleton. */ diff --git a/paper-api/src/main/java/org/bukkit/entity/Breeze.java b/paper-api/src/main/java/org/bukkit/entity/Breeze.java index 254bc6e18..6b41c9258 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Breeze.java +++ b/paper-api/src/main/java/org/bukkit/entity/Breeze.java @@ -1,7 +1,5 @@ package org.bukkit.entity; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a Breeze. Whoosh! */ diff --git a/paper-api/src/main/java/org/bukkit/entity/BreezeWindCharge.java b/paper-api/src/main/java/org/bukkit/entity/BreezeWindCharge.java index 748e58eb9..c37ee7cb2 100644 --- a/paper-api/src/main/java/org/bukkit/entity/BreezeWindCharge.java +++ b/paper-api/src/main/java/org/bukkit/entity/BreezeWindCharge.java @@ -1,7 +1,5 @@ package org.bukkit.entity; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a Wind Charge. */ diff --git a/paper-api/src/main/java/org/bukkit/entity/Creaking.java b/paper-api/src/main/java/org/bukkit/entity/Creaking.java index 6a7c952b6..2e85cc40e 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Creaking.java +++ b/paper-api/src/main/java/org/bukkit/entity/Creaking.java @@ -1,11 +1,8 @@ package org.bukkit.entity; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a Creaking. */ -@ApiStatus.Experimental public interface Creaking extends Monster { } diff --git a/paper-api/src/main/java/org/bukkit/entity/OminousItemSpawner.java b/paper-api/src/main/java/org/bukkit/entity/OminousItemSpawner.java index dbd4da4c6..1718277f5 100644 --- a/paper-api/src/main/java/org/bukkit/entity/OminousItemSpawner.java +++ b/paper-api/src/main/java/org/bukkit/entity/OminousItemSpawner.java @@ -1,7 +1,6 @@ package org.bukkit.entity; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; /** diff --git a/paper-api/src/main/java/org/bukkit/entity/WindCharge.java b/paper-api/src/main/java/org/bukkit/entity/WindCharge.java index beb624264..3baf72629 100644 --- a/paper-api/src/main/java/org/bukkit/entity/WindCharge.java +++ b/paper-api/src/main/java/org/bukkit/entity/WindCharge.java @@ -1,7 +1,5 @@ package org.bukkit.entity; -import org.jetbrains.annotations.ApiStatus; - /** * Represents a Wind Charge. */ diff --git a/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakBoat.java b/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakBoat.java index 604d46bb4..8b927c011 100644 --- a/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakBoat.java +++ b/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakBoat.java @@ -1,11 +1,9 @@ package org.bukkit.entity.boat; import org.bukkit.entity.Boat; -import org.jetbrains.annotations.ApiStatus; /** - * Represents an pale oak boat. + * Represents a pale oak boat. */ -@ApiStatus.Experimental public interface PaleOakBoat extends Boat { } diff --git a/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakChestBoat.java b/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakChestBoat.java index ebb5ae22e..97341eb01 100644 --- a/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakChestBoat.java +++ b/paper-api/src/main/java/org/bukkit/entity/boat/PaleOakChestBoat.java @@ -1,11 +1,9 @@ package org.bukkit.entity.boat; import org.bukkit.entity.ChestBoat; -import org.jetbrains.annotations.ApiStatus; /** - * Represents an pale oak chest boat. + * Represents a pale oak chest boat. */ -@ApiStatus.Experimental public interface PaleOakChestBoat extends ChestBoat { } diff --git a/paper-api/src/main/java/org/bukkit/inventory/CrafterInventory.java b/paper-api/src/main/java/org/bukkit/inventory/CrafterInventory.java index 49d0a37bb..0ce539fe9 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/CrafterInventory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/CrafterInventory.java @@ -1,7 +1,5 @@ package org.bukkit.inventory; -import org.jetbrains.annotations.ApiStatus; - /** * Interface to the inventory of a Crafter. */ diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/BundleMeta.java b/paper-api/src/main/java/org/bukkit/inventory/meta/BundleMeta.java index e404cd1e2..95bfdaa9e 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/BundleMeta.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/BundleMeta.java @@ -2,11 +2,9 @@ package org.bukkit.inventory.meta; import java.util.List; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -@ApiStatus.Experimental public interface BundleMeta extends ItemMeta { /** 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 e9cb8b46e..9acc6fa13 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 @@ -938,7 +938,7 @@ - player.resetSentInfo(); + // entityplayer.resetSentInfo(); + player.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange -+ player.refreshEntityData(player); // CraftBukkkit - SPIGOT-7218: sync metadata ++ player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected)); + // CraftBukkit start - from GameRules + int i = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23; diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch index 1b46405a4..1ba2e5608 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch @@ -9,7 +9,7 @@ int ageValue = state.getValue(AGE); if (ageValue < 2) { - level.setBlock(pos, state.setValue(AGE, Integer.valueOf(ageValue + 1)), 2); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(CocoaBlock.AGE, ageValue + 1), 2); // CraftBukkkit ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(CocoaBlock.AGE, ageValue + 1), 2); // CraftBukkit } } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java index 0191aa22a..0c67c2d55 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperEnchantmentRegistryEntry.java @@ -1,11 +1,9 @@ package io.papermc.paper.registry.data; -import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import io.papermc.paper.registry.PaperRegistryBuilder; import io.papermc.paper.registry.RegistryKey; -import io.papermc.paper.registry.TypedKey; import io.papermc.paper.registry.data.util.Checks; import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; @@ -189,7 +187,6 @@ public class PaperEnchantmentRegistryEntry implements EnchantmentRegistryEntry { @Override public Builder anvilCost(final @Range(from = 0, to = Integer.MAX_VALUE) int anvilCost) { - Preconditions.checkArgument(anvilCost >= 0, "anvilCost must be non-negative"); this.anvilCost = OptionalInt.of(asArgumentMin(anvilCost, "anvilCost", 0)); return this; } 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 bd8005cd3..a2e9f8fbc 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 @@ -590,7 +590,7 @@ public final class CraftMagicNumbers implements UnsafeValues { e.getStringUUID() ); } else { - // Ensure player flag is not needed + // Ensure misc flag is not needed Preconditions.checkArgument( nmsEntity.getType().canSerialize() || allowMiscSerialization, "Cannot serialize misc non-saveable entity %s(%s) without the MISC flag", From 5bcfb12a991a7449d2f7a966a824afb1c8749cbf Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Fri, 31 Jan 2025 13:13:14 +0100 Subject: [PATCH 083/203] Fix activation range config and water animal status (#12047) --- .../features/0003-Entity-Activation-Range-2.0.patch | 10 +++++----- .../paper/entity/activation/ActivationType.java | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch index dcb46b821..3a408ec3d 100644 --- a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch @@ -15,7 +15,7 @@ Adds villagers as separate config diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java new file mode 100644 -index 0000000000000000000000000000000000000000..bd888ef719b9bfc93bace0b1d0fb771ac659f515 +index 0000000000000000000000000000000000000000..ade6110cc6adb1263c0359ff7e96e96b959e61f3 --- /dev/null +++ b/io/papermc/paper/entity/activation/ActivationRange.java @@ -0,0 +1,318 @@ @@ -105,10 +105,10 @@ index 0000000000000000000000000000000000000000..bd888ef719b9bfc93bace0b1d0fb771a + * @return boolean If it should always tick. + */ + public static boolean initializeEntityActivationState(final Entity entity, final SpigotWorldConfig config) { -+ return (entity.activationType == ActivationType.MISC && config.miscActivationRange == 0) -+ || (entity.activationType == ActivationType.RAIDER && config.raiderActivationRange == 0) -+ || (entity.activationType == ActivationType.ANIMAL && config.animalActivationRange == 0) -+ || (entity.activationType == ActivationType.MONSTER && config.monsterActivationRange == 0) ++ return (entity.activationType == ActivationType.MISC && config.miscActivationRange <= 0) ++ || (entity.activationType == ActivationType.RAIDER && config.raiderActivationRange <= 0) ++ || (entity.activationType == ActivationType.ANIMAL && config.animalActivationRange <= 0) ++ || (entity.activationType == ActivationType.MONSTER && config.monsterActivationRange <= 0) + || (entity.activationType == ActivationType.VILLAGER && config.villagerActivationRange <= 0) + || (entity.activationType == ActivationType.WATER && config.waterActivationRange <= 0) + || (entity.activationType == ActivationType.FLYING_MONSTER && config.flyingMonsterActivationRange <= 0) diff --git a/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java b/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java index cd43845a0..bed83c589 100644 --- a/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java +++ b/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java @@ -4,6 +4,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.FlyingMob; import net.minecraft.world.entity.PathfinderMob; import net.minecraft.world.entity.ambient.AmbientCreature; +import net.minecraft.world.entity.animal.AgeableWaterCreature; import net.minecraft.world.entity.animal.WaterAnimal; import net.minecraft.world.entity.monster.Enemy; import net.minecraft.world.entity.npc.Villager; @@ -28,7 +29,7 @@ public enum ActivationType { * @return activation type */ public static ActivationType activationTypeFor(final Entity entity) { - if (entity instanceof WaterAnimal) { + if (entity instanceof WaterAnimal || entity instanceof AgeableWaterCreature) { return ActivationType.WATER; } else if (entity instanceof Villager) { return ActivationType.VILLAGER; From e0711af5d5b485ff507f5168c8c146689941421d Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Fri, 31 Jan 2025 13:17:45 +0100 Subject: [PATCH 084/203] Deprecate UnsafeValues#getSpawnEggLayerColor (#12041) --- .../src/main/java/org/bukkit/UnsafeValues.java | 14 ++++++++------ .../bukkit/craftbukkit/util/CraftMagicNumbers.java | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java index de34d0684..451ba8f49 100644 --- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java +++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java @@ -8,7 +8,6 @@ import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; -import org.bukkit.damage.DamageEffect; import org.bukkit.damage.DamageSource; import org.bukkit.damage.DamageType; import org.bukkit.entity.Entity; @@ -359,14 +358,17 @@ public interface UnsafeValues { // Paper start - spawn egg color visibility /** * Obtains the underlying color informating for a spawn egg of a given - * entity type, or null if the entity passed does not have a spawn egg. + * entity type, or {@code null} if the entity passed does not have a spawn egg. * Spawn eggs have two colors - the background layer (0), and the * foreground layer (1) - * @param entityType The entity type to get the color for - * @param layer The texture layer to get a color for - * @return The color of the layer for the entity's spawn egg + * + * @param entityType the entity type to get the color for + * @param layer the texture layer to get a color for + * @return the color of the layer for the entity's spawn egg + * @deprecated the color is no longer available to the server */ - @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); + @Deprecated(since = "1.21.4") + @Nullable Color getSpawnEggLayerColor(EntityType entityType, int layer); // Paper end - spawn egg color visibility // Paper start - lifecycle event API 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 a2e9f8fbc..59c0e8dbe 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 @@ -751,9 +751,9 @@ public final class CraftMagicNumbers implements UnsafeValues { final net.minecraft.world.entity.EntityType nmsType = org.bukkit.craftbukkit.entity.CraftEntityType.bukkitToMinecraft(entityType); final net.minecraft.world.item.SpawnEggItem eggItem = net.minecraft.world.item.SpawnEggItem.byId(nmsType); if (eggItem != null) { - throw new UnsupportedOperationException("Not yet implemented"); + throw new UnsupportedOperationException(); } - return eggItem == null ? null : org.bukkit.Color.fromRGB(1); // TODO + return null; } // Paper end - spawn egg color visibility From 8927091a08d81b939d80937b68aec684be1e3a27 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 2 Feb 2025 11:09:28 -0800 Subject: [PATCH 085/203] Do not record movement for vehicles/players unaffected by blocks If the player is not affected by movement through blocks, then storing the movement would eventually invoke logic to apply effects caused by moving through such blocks. For example, moving through a portal in spectator mode and then later switching to creative mode would portal the player. --- build-data/paper.at | 1 + ...vement-for-vehicles-players-unaffect.patch | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch diff --git a/build-data/paper.at b/build-data/paper.at index 26cdb6eaf..cf91314d9 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -186,6 +186,7 @@ public net.minecraft.world.entity.Entity getEncodeId()Ljava/lang/String; public net.minecraft.world.entity.Entity getFireImmuneTicks()I public net.minecraft.world.entity.Entity getSharedFlag(I)Z 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 diff --git a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch new file mode 100644 index 000000000..0e1eece0f --- /dev/null +++ b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Sun, 2 Feb 2025 10:57:48 -0800 +Subject: [PATCH] Do not record movement for vehicles/players unaffected by + blocks + +If the player is not affected by movement through blocks, then +storing the movement would eventually invoke logic to apply effects +caused by moving through such blocks. For example, moving through +a portal in spectator mode and then later switching to creative mode +would portal the player. + +diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +index 5738709f5fa6fee2ed88ba41a7718c976b780e96..882dbb1276c548316938bbc50f5f7e01f8547ff8 100644 +--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java +@@ -657,7 +657,7 @@ public class ServerGamePacketListenerImpl + // CraftBukkit end + + this.player.serverLevel().getChunkSource().move(this.player); +- rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position()); ++ if (!rootVehicle.isSpectator() && rootVehicle.isAffectedByBlocks()) rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position()); + Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z); + this.handlePlayerKnownMovement(vec3); + rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3); +@@ -1574,7 +1574,7 @@ public class ServerGamePacketListenerImpl + Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z); + this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3); + this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround()); +- this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position()); ++ if (!this.player.isSpectator() && this.player.isAffectedByBlocks()) this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position()); + this.handlePlayerKnownMovement(vec3); + if (flag) { + this.player.resetFallDistance(); From 5395ae37bd372235390d28292ed582d0c4fc23dd Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 2 Feb 2025 22:38:01 +0100 Subject: [PATCH 086/203] Fix composter block setting bukkit owner twice (#12058) --- .../world/level/block/ComposterBlock.java.patch | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch index 1306f54ed..5a21c3937 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch @@ -106,7 +106,7 @@ } @Override -@@ -381,9 +_,11 @@ +@@ -381,6 +_,7 @@ public InputContainer(BlockState state, LevelAccessor level, BlockPos pos) { super(1); @@ -114,10 +114,6 @@ this.state = state; this.level = level; this.pos = pos; -+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(level, pos, this); // CraftBukkit - } - - @Override @@ -412,6 +_,11 @@ if (!item.isEmpty()) { this.changed = true; @@ -130,6 +126,14 @@ this.level.levelEvent(1500, this.pos, blockState != this.state ? 1 : 0); this.removeItemNoUpdate(0); } +@@ -426,6 +_,7 @@ + + public OutputContainer(BlockState state, LevelAccessor level, BlockPos pos, ItemStack stack) { + super(stack); ++ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(level, pos, this); // Paper + this.state = state; + this.level = level; + this.pos = pos; @@ -453,8 +_,15 @@ @Override From 742968e078744a9d9fea35dc601cb6fecf05d889 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 4 Feb 2025 19:34:11 +0100 Subject: [PATCH 087/203] [ci skip] Increase outdated build delay to two weeks (#12063) --- paper-server/src/main/java/org/bukkit/craftbukkit/Main.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java b/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java index ecb0fcd1f..bf5343b08 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java @@ -263,11 +263,11 @@ public class Main { Date buildDate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z").parse(Main.class.getPackage().getImplementationVendor()); // Paper Calendar deadline = Calendar.getInstance(); - deadline.add(Calendar.DAY_OF_YEAR, -2); + deadline.add(Calendar.DAY_OF_YEAR, -14); if (buildDate.before(deadline.getTime())) { // Paper start - This is some stupid bullshit System.err.println("*** Warning, you've not updated in a while! ***"); - System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads/paper ***"); // Paper + System.err.println("*** Please download a new build from https://papermc.io/downloads/paper ***"); // Paper //System.err.println("*** Server will start in 20 seconds ***"); //Thread.sleep(TimeUnit.SECONDS.toMillis(20)); // Paper end From 597dcfffb9444f2c43a508a216e6f5d5eb712c04 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sat, 8 Feb 2025 18:07:43 +0000 Subject: [PATCH 088/203] Add support for lz4 (#12053) Mojang added this early 2024, however, it wasn't ever added to the actual config option inside of paper --- .../world/level/chunk/storage/RegionFileVersion.java.patch | 3 ++- .../io/papermc/paper/configuration/GlobalConfiguration.java | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFileVersion.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFileVersion.java.patch index ce1088103..86785dab5 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFileVersion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/RegionFileVersion.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/storage/RegionFileVersion.java +++ b/net/minecraft/world/level/chunk/storage/RegionFileVersion.java -@@ -61,6 +_,15 @@ +@@ -61,6 +_,16 @@ private final RegionFileVersion.StreamWrapper inputWrapper; private final RegionFileVersion.StreamWrapper outputWrapper; @@ -9,6 +9,7 @@ + return switch (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.compressionFormat) { + case GZIP -> VERSION_GZIP; + case ZLIB -> VERSION_DEFLATE; ++ case LZ4 -> VERSION_LZ4; + case NONE -> VERSION_NONE; + }; + } 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 d4a0b684e..bacd1d90a 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 @@ -186,6 +186,7 @@ public class GlobalConfiguration extends ConfigurationPart { public enum CompressionFormat { GZIP, ZLIB, + LZ4, NONE } } From 53ae5c95b71d6621bfd4b53c6792bb90652e1e9e Mon Sep 17 00:00:00 2001 From: David <54660361+NonSwag@users.noreply.github.com> Date: Sat, 8 Feb 2025 20:16:23 +0100 Subject: [PATCH 089/203] Make Sittable interface extend Entity (#12016) --- .../src/main/java/org/bukkit/entity/Panda.java | 16 ---------------- .../main/java/org/bukkit/entity/Sittable.java | 8 ++++---- .../craftbukkit/entity/EntityTypesTest.java | 2 ++ 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Panda.java b/paper-api/src/main/java/org/bukkit/entity/Panda.java index 4f06870cc..cfe00e42f 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Panda.java +++ b/paper-api/src/main/java/org/bukkit/entity/Panda.java @@ -171,22 +171,6 @@ public interface Panda extends Animals, Sittable { this.setSitting(sitting); } - /** - * Sets if this panda is currently sitting. - * - * @param sitting is currently sitting - */ - @Override - void setSitting(boolean sitting); - - /** - * Gets if this panda is sitting. - * - * @return is sitting - */ - @Override - boolean isSitting(); - /** * Gets this Panda's combined gene. *

diff --git a/paper-api/src/main/java/org/bukkit/entity/Sittable.java b/paper-api/src/main/java/org/bukkit/entity/Sittable.java index ea6ee26fc..f873e9492 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Sittable.java +++ b/paper-api/src/main/java/org/bukkit/entity/Sittable.java @@ -1,19 +1,19 @@ package org.bukkit.entity; /** - * An animal that can sit still. + * An entity that can sit still. */ -public interface Sittable { +public interface Sittable extends Entity { /** - * Checks if this animal is sitting + * Checks if this entity is sitting * * @return true if sitting */ boolean isSitting(); /** - * Sets if this animal is sitting. Will remove any path that the animal + * Sets if this entity is sitting. Will remove any path that the entity * was following beforehand. * * @param sitting true if sitting diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/entity/EntityTypesTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/entity/EntityTypesTest.java index b638519bb..ff294e6fd 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/entity/EntityTypesTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/entity/EntityTypesTest.java @@ -49,6 +49,7 @@ import org.bukkit.entity.NPC; import org.bukkit.entity.PiglinAbstract; import org.bukkit.entity.Projectile; import org.bukkit.entity.Raider; +import org.bukkit.entity.Sittable; import org.bukkit.entity.SizedFireball; import org.bukkit.entity.Spellcaster; import org.bukkit.entity.SplashPotion; @@ -110,6 +111,7 @@ public class EntityTypesTest { PiglinAbstract.class, Projectile.class, Raider.class, + Sittable.class, SizedFireball.class, Spellcaster.class, SplashPotion.class, From 786ddf53c699f101fe54e76a1e107dbeb4c36575 Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Sat, 8 Feb 2025 21:17:45 +0200 Subject: [PATCH 090/203] Default piston block entity direction to DOWN (#12039) --- .../block/piston/PistonMovingBlockEntity.java.patch | 9 +++++++++ .../bukkit/craftbukkit/block/CraftBlockEntityState.java | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch index 2774d551a..afaa13a66 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch @@ -1,5 +1,14 @@ --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +@@ -35,7 +_,7 @@ + private static final double PUSH_OFFSET = 0.01; + public static final double TICK_MOVEMENT = 0.51; + private BlockState movedState = Blocks.AIR.defaultBlockState(); +- private Direction direction; ++ private Direction direction = Direction.DOWN; // Paper - default to first value to avoid NPE + private boolean extending; + private boolean isSourcePiston; + private static final ThreadLocal NOCLIP = ThreadLocal.withInitial(() -> null); @@ -299,7 +_,7 @@ if (level.getBlockState(pos).is(Blocks.MOVING_PISTON)) { BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, level, pos); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java index 04ae258a2..768d3f93d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java @@ -50,7 +50,12 @@ public abstract class CraftBlockEntityState extends Craft if (thr instanceof ThreadDeath) { throw (ThreadDeath)thr; } - throw new RuntimeException("Failed to read BlockState at: world: " + this.getWorld().getName() + " location: (" + this.getX() + ", " + this.getY() + ", " + this.getZ() + ")", thr); + throw new RuntimeException( + world == null + ? "Failed to read non-placed BlockState" + : "Failed to read BlockState at: world: " + world.getName() + " location: (" + this.getX() + ", " + this.getY() + ", " + this.getZ() + ")", + thr + ); } // Paper end - Show blockstate location if we failed to read it } From cb6c57e0f8324e07090598e5117c37574c3dd014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roni=20=C3=84ik=C3=A4s?= Date: Sat, 8 Feb 2025 21:24:07 +0200 Subject: [PATCH 091/203] Fix Squid and Dolphin spawn height (#12045) --- .../entity/animal/AgeableWaterCreature.java.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/animal/AgeableWaterCreature.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/AgeableWaterCreature.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/AgeableWaterCreature.java.patch new file mode 100644 index 000000000..a88fad2a6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/AgeableWaterCreature.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/entity/animal/AgeableWaterCreature.java ++++ b/net/minecraft/world/entity/animal/AgeableWaterCreature.java +@@ -68,6 +_,10 @@ + ) { + int seaLevel = level.getSeaLevel(); + int i = seaLevel - 13; ++ // Paper start - Make water animal spawn height configurable ++ seaLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(seaLevel); ++ i = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(i); ++ // Paper end - Make water animal spawn height configurable + return pos.getY() >= i + && pos.getY() <= seaLevel + && level.getFluidState(pos.below()).is(FluidTags.WATER) From 51acc802b85ba2da9583b06a0e29405905f23722 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Feb 2025 20:55:57 +0100 Subject: [PATCH 092/203] Prevent duplicate raider in RaidSpawnWaveEvent list (#12040) --- .../world/entity/raid/Raid.java.patch | 38 ++++--------------- .../craftbukkit/event/CraftEventFactory.java | 16 ++++---- 2 files changed, 16 insertions(+), 38 deletions(-) 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 f5c2c2d98..52c955c67 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 @@ -99,42 +99,20 @@ this.stop(); return; } -@@ -491,6 +_,10 @@ +@@ -486,7 +_,7 @@ + + private void spawnGroup(BlockPos pos) { + boolean flag = false; +- int i = this.groupsSpawned + 1; ++ int i = this.groupsSpawned + 1; final int wave = i; // Paper - OBFHELPER + this.totalHealth = 0.0F; DifficultyInstance currentDifficultyAt = this.level.getCurrentDifficultyAt(pos); boolean shouldSpawnBonusGroup = this.shouldSpawnBonusGroup(); - -+ // CraftBukkit start -+ Raider leader = null; -+ List raiders = new java.util.ArrayList<>(); -+ // CraftBukkit end - for (Raid.RaiderType raiderType : Raid.RaiderType.VALUES) { - int i1 = this.getDefaultNumSpawns(raiderType, i, shouldSpawnBonusGroup) - + this.getPotentialBonusSpawns(raiderType, this.random, i, currentDifficultyAt, shouldSpawnBonusGroup); -@@ -506,9 +_,11 @@ - raider.setPatrolLeader(true); - this.setLeader(i, raider); - flag = true; -+ leader = raider; // CraftBukkit - } - - this.joinRaid(i, raider, pos, false); -+ raiders.add(raider); // CraftBukkit - if (raiderType.entityType == EntityType.RAVAGER) { - Raider raider1 = null; - if (i == this.getNumGroups(Difficulty.NORMAL)) { -@@ -526,6 +_,7 @@ - this.joinRaid(i, raider1, pos, false); - raider1.moveTo(pos, 0.0F, 0.0F); - raider1.startRiding(raider); -+ raiders.add(raider); // CraftBukkit - } - } - } @@ -535,6 +_,7 @@ this.groupsSpawned++; this.updateBossbar(); this.setDirty(); -+ org.bukkit.craftbukkit.event.CraftEventFactory.callRaidSpawnWaveEvent(this, leader, raiders); // CraftBukkit ++ org.bukkit.craftbukkit.event.CraftEventFactory.callRaidSpawnWaveEvent(this, java.util.Objects.requireNonNull(this.getLeader(wave)), this.groupRaiderMap.get(wave)); // CraftBukkit } public void joinRaid(int wave, Raider raider, @Nullable BlockPos pos, boolean isRecruited) { 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 d7a52220e..85adadf7d 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 @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.EnumMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; @@ -87,7 +88,6 @@ import org.bukkit.craftbukkit.damage.CraftDamageSource; import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.craftbukkit.entity.CraftPlayer; -import org.bukkit.craftbukkit.entity.CraftRaider; import org.bukkit.craftbukkit.entity.CraftSpellcaster; import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -2015,14 +2015,14 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(event); } - public static void callRaidSpawnWaveEvent(Raid raid, net.minecraft.world.entity.raid.Raider leader, List raiders) { - Raider craftLeader = (CraftRaider) leader.getBukkitEntity(); - List craftRaiders = new ArrayList<>(); - for (net.minecraft.world.entity.raid.Raider entityRaider : raiders) { - craftRaiders.add((Raider) entityRaider.getBukkitEntity()); + public static void callRaidSpawnWaveEvent(Raid raid, net.minecraft.world.entity.raid.Raider leader, Set raiders) { + Raider bukkitLeader = (Raider) leader.getBukkitEntity(); + List bukkitRaiders = new ArrayList<>(raiders.size()); + for (net.minecraft.world.entity.raid.Raider raider : raiders) { + bukkitRaiders.add((Raider) raider.getBukkitEntity()); } - RaidSpawnWaveEvent event = new RaidSpawnWaveEvent(new CraftRaid(raid), raid.getLevel().getWorld(), craftLeader, craftRaiders); - Bukkit.getPluginManager().callEvent(event); + RaidSpawnWaveEvent event = new RaidSpawnWaveEvent(new CraftRaid(raid), raid.getLevel().getWorld(), bukkitLeader, bukkitRaiders); + event.callEvent(); } public static LootGenerateEvent callLootGenerateEvent(Container inventory, LootTable lootTable, LootContext lootInfo, List loot, boolean plugin) { From 61312fdb592766e3662c50a60ee23f55da6aac3e Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 8 Feb 2025 12:57:35 -0700 Subject: [PATCH 093/203] Switch to jspecify annotations for Player (#12042) Fixes compilation issues for plugins from recent API addition with double-annotated parameter (JetBrains annotations are type-use and parameter, so nonnull array of nonnull elements ends up with duplicates) --- .../main/java/org/bukkit/OfflinePlayer.java | 56 ++- .../java/org/bukkit/entity/HumanEntity.java | 71 ++-- .../main/java/org/bukkit/entity/Player.java | 344 ++++++++---------- 3 files changed, 215 insertions(+), 256 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/OfflinePlayer.java b/paper-api/src/main/java/org/bukkit/OfflinePlayer.java index 5622fe316..ed8e11001 100644 --- a/paper-api/src/main/java/org/bukkit/OfflinePlayer.java +++ b/paper-api/src/main/java/org/bukkit/OfflinePlayer.java @@ -11,14 +11,15 @@ import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.permissions.ServerOperator; import org.bukkit.profile.PlayerProfile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents a reference to a player identity and the data belonging to a * player that is stored on the disk and can, thus, be retrieved without the * player needing to be online. */ +@NullMarked public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, io.papermc.paper.persistence.PersistentDataViewHolder { // Paper - Add Offline PDC API /** @@ -62,7 +63,6 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @return Player UUID */ @Override - @NotNull public UUID getUniqueId(); /** @@ -74,7 +74,6 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * * @return the player's profile */ - @NotNull com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile(); // Paper /** @@ -91,7 +90,6 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} */ - @NotNull @Deprecated(since = "1.20.4") public default BanEntry banPlayer(@Nullable String reason) { return banPlayer(reason, null, null); @@ -104,7 +102,6 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} */ - @NotNull @Deprecated(since = "1.20.4") public default BanEntry banPlayer(@Nullable String reason, @Nullable String source) { return banPlayer(reason, null, source); @@ -117,9 +114,8 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} */ - @NotNull @Deprecated(since = "1.20.4") - public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires) { + public default BanEntry banPlayer(@Nullable String reason, java.util.@Nullable Date expires) { return banPlayer(reason, expires, null); } @@ -131,18 +127,16 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} */ - @NotNull @Deprecated(since = "1.20.4") - public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source) { + public default BanEntry banPlayer(@Nullable String reason, java.util.@Nullable Date expires, @Nullable String source) { return banPlayer(reason, expires, source, true); } /** * @deprecated use {@link #ban(String, Date, String)} */ - @NotNull @Deprecated(since = "1.20.4") - public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source, boolean kickIfOnline) { + public default BanEntry banPlayer(@Nullable String reason, java.util.@Nullable Date expires, @Nullable String source, boolean kickIfOnline) { BanEntry banEntry = Bukkit.getServer().getBanList(BanList.Type.NAME).addBan(getName(), reason, expires, source); if (kickIfOnline && isOnline()) { getPlayer().kickPlayer(reason); @@ -309,7 +303,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the statistic requires an * additional parameter */ - public void incrementStatistic(@NotNull Statistic statistic) throws IllegalArgumentException; + public void incrementStatistic(Statistic statistic) throws IllegalArgumentException; /** * Decrements the given statistic for this player. @@ -322,7 +316,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the statistic requires an * additional parameter */ - public void decrementStatistic(@NotNull Statistic statistic) throws IllegalArgumentException; + public void decrementStatistic(Statistic statistic) throws IllegalArgumentException; /** * Increments the given statistic for this player. @@ -334,7 +328,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the statistic requires an * additional parameter */ - public void incrementStatistic(@NotNull Statistic statistic, int amount) throws IllegalArgumentException; + public void incrementStatistic(Statistic statistic, int amount) throws IllegalArgumentException; /** * Decrements the given statistic for this player. @@ -346,7 +340,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the statistic requires an * additional parameter */ - public void decrementStatistic(@NotNull Statistic statistic, int amount) throws IllegalArgumentException; + public void decrementStatistic(Statistic statistic, int amount) throws IllegalArgumentException; /** * Sets the given statistic for this player. @@ -358,7 +352,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the statistic requires an * additional parameter */ - public void setStatistic(@NotNull Statistic statistic, int newValue) throws IllegalArgumentException; + public void setStatistic(Statistic statistic, int newValue) throws IllegalArgumentException; /** * Gets the value of the given statistic for this player. @@ -369,7 +363,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the statistic requires an * additional parameter */ - public int getStatistic(@NotNull Statistic statistic) throws IllegalArgumentException; + public int getStatistic(Statistic statistic) throws IllegalArgumentException; /** * Increments the given statistic for this player for the given material. @@ -384,7 +378,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void incrementStatistic(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException; + public void incrementStatistic(Statistic statistic, Material material) throws IllegalArgumentException; /** * Decrements the given statistic for this player for the given material. @@ -399,7 +393,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void decrementStatistic(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException; + public void decrementStatistic(Statistic statistic, Material material) throws IllegalArgumentException; /** * Gets the value of the given statistic for this player. @@ -412,7 +406,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public int getStatistic(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException; + public int getStatistic(Statistic statistic, Material material) throws IllegalArgumentException; /** * Increments the given statistic for this player for the given material. @@ -426,7 +420,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void incrementStatistic(@NotNull Statistic statistic, @NotNull Material material, int amount) throws IllegalArgumentException; + public void incrementStatistic(Statistic statistic, Material material, int amount) throws IllegalArgumentException; /** * Decrements the given statistic for this player for the given material. @@ -440,7 +434,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void decrementStatistic(@NotNull Statistic statistic, @NotNull Material material, int amount) throws IllegalArgumentException; + public void decrementStatistic(Statistic statistic, Material material, int amount) throws IllegalArgumentException; /** * Sets the given statistic for this player for the given material. @@ -454,7 +448,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void setStatistic(@NotNull Statistic statistic, @NotNull Material material, int newValue) throws IllegalArgumentException; + public void setStatistic(Statistic statistic, Material material, int newValue) throws IllegalArgumentException; /** * Increments the given statistic for this player for the given entity. @@ -469,7 +463,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void incrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException; + public void incrementStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException; /** * Decrements the given statistic for this player for the given entity. @@ -484,7 +478,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void decrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException; + public void decrementStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException; /** * Gets the value of the given statistic for this player. @@ -497,7 +491,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public int getStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException; + public int getStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException; /** * Increments the given statistic for this player for the given entity. @@ -511,7 +505,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void incrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType, int amount) throws IllegalArgumentException; + public void incrementStatistic(Statistic statistic, EntityType entityType, int amount) throws IllegalArgumentException; /** * Decrements the given statistic for this player for the given entity. @@ -525,7 +519,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void decrementStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType, int amount); + public void decrementStatistic(Statistic statistic, EntityType entityType, int amount); /** * Sets the given statistic for this player for the given entity. @@ -539,7 +533,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @throws IllegalArgumentException if the given parameter is not valid * for the statistic */ - public void setStatistic(@NotNull Statistic statistic, @NotNull EntityType entityType, int newValue); + public void setStatistic(Statistic statistic, EntityType entityType, int newValue); /** * Gets the player's last death location. @@ -571,6 +565,6 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio * @see io.papermc.paper.persistence.PersistentDataViewHolder#getPersistentDataContainer() */ @Override - io.papermc.paper.persistence.@NotNull PersistentDataContainerView getPersistentDataContainer(); + io.papermc.paper.persistence.PersistentDataContainerView getPersistentDataContainer(); // Paper end - add pdc to offline player } 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 34538999e..9811e7983 100644 --- a/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java +++ b/paper-api/src/main/java/org/bukkit/entity/HumanEntity.java @@ -18,17 +18,18 @@ import org.bukkit.inventory.Merchant; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.FireworkMeta; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents a human entity, such as an NPC or a player */ +@NullMarked public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder { // Paper start @Override - org.bukkit.inventory.@NotNull EntityEquipment getEquipment(); + org.bukkit.inventory.EntityEquipment getEquipment(); // Paper end /** @@ -36,7 +37,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return Player name */ - @NotNull @Override public String getName(); @@ -46,7 +46,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return The inventory of the player, this also contains the armor * slots. */ - @NotNull @Override public PlayerInventory getInventory(); @@ -55,7 +54,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return The EnderChest of the player */ - @NotNull public Inventory getEnderChest(); /** @@ -63,7 +61,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return the players main hand */ - @NotNull public MainHand getMainHand(); /** @@ -76,7 +73,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @deprecated use {@link InventoryView} and its children. */ @Deprecated(forRemoval = true, since = "1.21") - public boolean setWindowProperty(@NotNull InventoryView.Property prop, int value); + public boolean setWindowProperty(InventoryView.Property prop, int value); /** * Gets the player's current enchantment seed. @@ -104,7 +101,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return The inventory view. */ - @NotNull public InventoryView getOpenInventory(); /** @@ -115,7 +111,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return The newly opened inventory view */ @Nullable - public InventoryView openInventory(@NotNull Inventory inventory); + public InventoryView openInventory(Inventory inventory); /** * Opens an empty workbench inventory window with the player's inventory @@ -162,7 +158,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @param inventory The view to open */ - public void openInventory(@NotNull InventoryView inventory); + public void openInventory(InventoryView inventory); /** * Starts a trade between the player and the villager. @@ -178,7 +174,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder */ @Deprecated(since = "1.21.4") @Nullable - public InventoryView openMerchant(@NotNull Villager trader, boolean force); + public InventoryView openMerchant(Villager trader, boolean force); /** * Starts a trade between the player and the merchant. @@ -194,7 +190,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder */ @Deprecated(since = "1.21.4") @Nullable - public InventoryView openMerchant(@NotNull Merchant merchant, boolean force); + public InventoryView openMerchant(Merchant merchant, boolean force); // Paper start - Add additional containers /** @@ -311,7 +307,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @param reason why the inventory is closing */ - public void closeInventory(@NotNull org.bukkit.event.inventory.InventoryCloseEvent.Reason reason); + public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason); // Paper end /** @@ -322,7 +318,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * methods in {@link PlayerInventory}. */ @Deprecated(since = "1.9") - @NotNull public ItemStack getItemInHand(); /** @@ -342,7 +337,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return The ItemStack of the item you are currently moving around. */ - @NotNull public ItemStack getItemOnCursor(); /** @@ -361,7 +355,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return if a cooldown is active on the material * @throws IllegalArgumentException if the material is not an item */ - public boolean hasCooldown(@NotNull Material material); + public boolean hasCooldown(Material material); /** * Get the cooldown time in ticks remaining for the specified material. @@ -370,7 +364,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return the remaining cooldown time in ticks * @throws IllegalArgumentException if the material is not an item */ - public int getCooldown(@NotNull Material material); + public int getCooldown(Material material); /** * Set a cooldown on the specified material for a certain amount of ticks. @@ -386,7 +380,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param ticks the amount of ticks to set or 0 to remove * @throws IllegalArgumentException if the material is not an item */ - public void setCooldown(@NotNull Material material, int ticks); + public void setCooldown(Material material, int ticks); // Paper start /** @@ -413,7 +407,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param item the item to check * @return if a cooldown is active on the item */ - public boolean hasCooldown(@NotNull ItemStack item); + public boolean hasCooldown(ItemStack item); /** * Get the cooldown time in ticks remaining for the specified item. @@ -421,7 +415,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param item the item to check * @return the remaining cooldown time in ticks */ - public int getCooldown(@NotNull ItemStack item); + public int getCooldown(ItemStack item); /** * Set a cooldown on the specified item for a certain amount of ticks. @@ -436,7 +430,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param item the item to set the cooldown for * @param ticks the amount of ticks to set or 0 to remove */ - public void setCooldown(@NotNull ItemStack item, int ticks); + public void setCooldown(ItemStack item, int ticks); /** * Get the sleep ticks of the player. This value may be capped. @@ -493,7 +487,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * normally possible * @return whether the sleep was successful */ - public boolean sleep(@NotNull Location location, boolean force); + public boolean sleep(Location location, boolean force); /** * Causes the player to wakeup if they are currently sleeping. @@ -519,7 +513,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return location * @throws IllegalStateException if not sleeping */ - @NotNull public Location getBedLocation(); /** @@ -527,7 +520,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return Current game mode */ - @NotNull public GameMode getGameMode(); /** @@ -535,7 +527,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @param mode New game mode */ - public void setGameMode(@NotNull GameMode mode); + public void setGameMode(GameMode mode); /** * Check if the player is currently blocking (ie with a shield). @@ -600,7 +592,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return whether or not the recipe was newly discovered */ - public boolean discoverRecipe(@NotNull NamespacedKey recipe); + public boolean discoverRecipe(NamespacedKey recipe); /** * Discover a collection of recipes for this player such that they have not @@ -614,7 +606,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * none were newly discovered and a number equal to {@code recipes.size()} * indicates that all were new */ - public int discoverRecipes(@NotNull Collection recipes); + public int discoverRecipes(Collection recipes); /** * Undiscover a recipe for this player such that it has already been @@ -626,7 +618,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return whether or not the recipe was successfully undiscovered (i.e. it * was previously discovered) */ - public boolean undiscoverRecipe(@NotNull NamespacedKey recipe); + public boolean undiscoverRecipe(NamespacedKey recipe); /** * Undiscover a collection of recipes for this player such that they have @@ -640,7 +632,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * were undiscovered and a number equal to {@code recipes.size()} indicates * that all were undiscovered */ - public int undiscoverRecipes(@NotNull Collection recipes); + public int undiscoverRecipes(Collection recipes); /** * Check whether or not this entity has discovered the specified recipe. @@ -649,14 +641,13 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * * @return true if discovered, false otherwise */ - public boolean hasDiscoveredRecipe(@NotNull NamespacedKey recipe); + public boolean hasDiscoveredRecipe(NamespacedKey recipe); /** * Get an immutable set of recipes this entity has discovered. * * @return all discovered recipes */ - @NotNull public Set getDiscoveredRecipes(); /** @@ -730,7 +721,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @deprecated use {@link #openSign(org.bukkit.block.Sign, org.bukkit.block.sign.Side)} */ @Deprecated - default void openSign(@NotNull org.bukkit.block.Sign sign) { + default void openSign(org.bukkit.block.Sign sign) { this.openSign(sign, org.bukkit.block.sign.Side.FRONT); } @@ -740,7 +731,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @param sign The sign to open * @param side The side of the sign to open */ - void openSign(org.bukkit.block.@NotNull Sign sign, org.bukkit.block.sign.@NotNull Side side); + void openSign(org.bukkit.block.Sign sign, org.bukkit.block.sign.Side side); // Paper end /** @@ -801,7 +792,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return the dropped item entity, or null if the action was unsuccessful */ @Nullable - default Item dropItem(final @NotNull EquipmentSlot slot) { + default Item dropItem(final EquipmentSlot slot) { return this.dropItem(slot, Integer.MAX_VALUE); } @@ -813,7 +804,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return the dropped item entity, or null if the action was unsuccessful */ @Nullable - default Item dropItem(final @NotNull EquipmentSlot slot, final int amount) { + default Item dropItem(final EquipmentSlot slot, final int amount) { return this.dropItem(slot, amount, false, null); } @@ -828,7 +819,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return the dropped item entity, or null if the action was unsuccessful */ @Nullable - Item dropItem(@NotNull EquipmentSlot slot, int amount, boolean throwRandomly, @Nullable Consumer entityOperation); + Item dropItem(EquipmentSlot slot, int amount, boolean throwRandomly, @Nullable Consumer entityOperation); /** * Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually @@ -841,7 +832,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return the dropped item entity, or null if the action was unsuccessful */ @Nullable - default Item dropItem(final @NotNull ItemStack itemStack) { + default Item dropItem(final ItemStack itemStack) { return this.dropItem(itemStack, false, null); } @@ -859,7 +850,7 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @return the dropped item entity, or null if the action was unsuccessful */ @Nullable - Item dropItem(final @NotNull ItemStack itemStack, boolean throwRandomly, @Nullable Consumer entityOperation); + Item dropItem(final ItemStack itemStack, boolean throwRandomly, @Nullable Consumer entityOperation); /** * Gets the players current exhaustion level. @@ -996,6 +987,6 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder * @throws IllegalArgumentException if the fireworkItemStack is not a firework */ @Nullable - public Firework fireworkBoost(@NotNull ItemStack fireworkItemStack); + public Firework fireworkBoost(ItemStack fireworkItemStack); } 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 dd0438516..0081dd53b 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Player.java +++ b/paper-api/src/main/java/org/bukkit/entity/Player.java @@ -55,17 +55,18 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.profile.PlayerProfile; import org.bukkit.scoreboard.Scoreboard; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents a player, connected or not */ +@NullMarked public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, net.kyori.adventure.bossbar.BossBarViewer, com.destroystokyo.paper.network.NetworkClient { // Paper // Paper start @Override - default net.kyori.adventure.identity.@NotNull Identity identity() { + default net.kyori.adventure.identity.Identity identity() { return net.kyori.adventure.identity.Identity.identity(this.getUniqueId()); } @@ -80,14 +81,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @since 4.14.0 */ @Override - @org.jetbrains.annotations.UnmodifiableView @NotNull Iterable activeBossBars(); + @org.jetbrains.annotations.UnmodifiableView Iterable activeBossBars(); /** * Gets the "friendly" name to display of this player. * * @return the display name */ - net.kyori.adventure.text.@NotNull Component displayName(); + net.kyori.adventure.text.Component displayName(); /** * Sets the "friendly" name to display of this player. @@ -100,7 +101,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * {@inheritDoc} */ - @NotNull @Override public String getName(); @@ -115,7 +115,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #displayName()} */ @Deprecated // Paper - @NotNull public String getDisplayName(); /** @@ -146,7 +145,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return the player list name */ - net.kyori.adventure.text.@NotNull Component playerListName(); + net.kyori.adventure.text.Component playerListName(); /** * Gets the currently displayed player list header for this player. @@ -168,7 +167,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return the player list name * @deprecated in favour of {@link #playerListName()} */ - @NotNull @Deprecated // Paper public String getPlayerListName(); @@ -252,14 +250,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param loc Location to point to */ - public void setCompassTarget(@NotNull Location loc); + public void setCompassTarget(Location loc); /** * Get the previously set compass target. * * @return location of the target */ - @NotNull public Location getCompassTarget(); /** @@ -296,8 +293,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * set in the client, the {@link CompletableFuture} will complete with a * null value. */ - @NotNull - CompletableFuture retrieveCookie(@NotNull NamespacedKey key); + CompletableFuture retrieveCookie(NamespacedKey key); /** * Stores a cookie in this player's client. @@ -306,7 +302,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param value the data to store in the cookie * @throws IllegalStateException if a cookie cannot be stored at this time */ - void storeCookie(@NotNull NamespacedKey key, @NotNull byte[] value); + void storeCookie(NamespacedKey key, byte[] value); /** * Requests this player to connect to a different server specified by host @@ -317,7 +313,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalStateException if a transfer cannot take place at this * time */ - void transfer(@NotNull String host, int port); + void transfer(String host, int port); /** * Sends this sender a message raw @@ -325,7 +321,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param message Message to be displayed */ @Override - public void sendRawMessage(@NotNull String message); + public void sendRawMessage(String message); /** * Kicks player with custom kick message. @@ -355,7 +351,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param message kick message * @param cause kick cause */ - void kick(final net.kyori.adventure.text.@Nullable Component message, org.bukkit.event.player.PlayerKickEvent.@NotNull Cause cause); + void kick(final net.kyori.adventure.text.@Nullable Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause); // Paper end /** @@ -459,7 +455,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param msg message to print */ - public void chat(@NotNull String msg); + public void chat(String msg); /** * Makes the player perform the given command @@ -467,7 +463,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param command Command to perform * @return true if the command was successful, otherwise false */ - public boolean performCommand(@NotNull String command); + public boolean performCommand(String command); /** * Returns true if the entity is supported by a block. @@ -622,7 +618,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return collection of entities corresponding to current pearls. */ - @NotNull @ApiStatus.Experimental public Collection getEnderPearls(); @@ -634,7 +629,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return current input */ - @NotNull @ApiStatus.Experimental public Input getCurrentInput(); @@ -648,7 +642,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Magic value */ @Deprecated(since = "1.6.2") - public void playNote(@NotNull Location loc, byte instrument, byte note); + public void playNote(Location loc, byte instrument, byte note); /** * Play a note for the player at a location.
@@ -659,7 +653,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param instrument The instrument * @param note The note */ - public void playNote(@NotNull Location loc, @NotNull Instrument instrument, @NotNull Note note); + public void playNote(Location loc, Instrument instrument, Note note); /** @@ -672,7 +666,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Location location, @NotNull Sound sound, float volume, float pitch); + public void playSound(Location location, Sound sound, float volume, float pitch); /** * Play a sound for a player at the location. @@ -686,7 +680,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Location location, @NotNull String sound, float volume, float pitch); + public void playSound(Location location, String sound, float volume, float pitch); /** * Play a sound for a player at the location. @@ -699,7 +693,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch); + public void playSound(Location location, Sound sound, SoundCategory category, float volume, float pitch); /** * Play a sound for a player at the location. @@ -714,7 +708,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch); + public void playSound(Location location, String sound, SoundCategory category, float volume, float pitch); /** * Play a sound for a player at the location. For sounds with multiple @@ -729,7 +723,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param pitch The pitch of the sound * @param seed The seed for the sound */ - public void playSound(@NotNull Location location, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + public void playSound(Location location, Sound sound, SoundCategory category, float volume, float pitch, long seed); /** * Play a sound for a player at the location. For sounds with multiple @@ -746,7 +740,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param pitch The pitch of the sound * @param seed The seed for the sound */ - public void playSound(@NotNull Location location, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + public void playSound(Location location, String sound, SoundCategory category, float volume, float pitch, long seed); /** * Play a sound for a player at the location of the entity. @@ -758,7 +752,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Entity entity, @NotNull Sound sound, float volume, float pitch); + public void playSound(Entity entity, Sound sound, float volume, float pitch); /** * Play a sound for a player at the location of the entity. @@ -770,7 +764,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Entity entity, @NotNull String sound, float volume, float pitch); + public void playSound(Entity entity, String sound, float volume, float pitch); /** * Play a sound for a player at the location of the entity. @@ -783,7 +777,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch); + public void playSound(Entity entity, Sound sound, SoundCategory category, float volume, float pitch); /** * Play a sound for a player at the location of the entity. @@ -796,7 +790,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param volume The volume of the sound * @param pitch The pitch of the sound */ - public void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch); + public void playSound(Entity entity, String sound, SoundCategory category, float volume, float pitch); /** * Play a sound for a player at the location of the entity. For sounds with @@ -811,7 +805,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param pitch The pitch of the sound * @param seed The seed for the sound */ - public void playSound(@NotNull Entity entity, @NotNull Sound sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + public void playSound(Entity entity, Sound sound, SoundCategory category, float volume, float pitch, long seed); /** * Play a sound for a player at the location of the entity. For sounds with @@ -826,21 +820,21 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param pitch The pitch of the sound * @param seed The seed for the sound */ - public void playSound(@NotNull Entity entity, @NotNull String sound, @NotNull SoundCategory category, float volume, float pitch, long seed); + public void playSound(Entity entity, String sound, SoundCategory category, float volume, float pitch, long seed); /** * Stop the specified sound from playing. * * @param sound the sound to stop */ - public void stopSound(@NotNull Sound sound); + public void stopSound(Sound sound); /** * Stop the specified sound from playing. * * @param sound the sound to stop */ - public void stopSound(@NotNull String sound); + public void stopSound(String sound); /** * Stop the specified sound from playing. @@ -848,7 +842,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param sound the sound to stop * @param category the category of the sound */ - public void stopSound(@NotNull Sound sound, @Nullable SoundCategory category); + public void stopSound(Sound sound, @Nullable SoundCategory category); /** * Stop the specified sound from playing. @@ -856,14 +850,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param sound the sound to stop * @param category the category of the sound */ - public void stopSound(@NotNull String sound, @Nullable SoundCategory category); + public void stopSound(String sound, @Nullable SoundCategory category); /** * Stop the specified sound category from playing. * * @param category the sound category to stop */ - public void stopSound(@NotNull SoundCategory category); + public void stopSound(SoundCategory category); /** * Stop all sounds from playing. @@ -879,7 +873,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Magic value */ @Deprecated(since = "1.6.2") - public void playEffect(@NotNull Location loc, @NotNull Effect effect, int data); + public void playEffect(Location loc, Effect effect, int data); /** * Plays an effect to just this player. @@ -889,7 +883,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param effect the {@link Effect} * @param data a data bit needed for some effects */ - public void playEffect(@NotNull Location loc, @NotNull Effect effect, @Nullable T data); + public void playEffect(Location loc, Effect effect, @Nullable T data); /** * Force this player to break a Block using the item in their main hand. @@ -913,7 +907,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return true if the block was broken, false if the break failed */ - public boolean breakBlock(@NotNull Block block); + public boolean breakBlock(Block block); /** * Send a block change. This fakes a block change packet for a user at a @@ -925,7 +919,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Magic value */ @Deprecated(since = "1.6.2") - public void sendBlockChange(@NotNull Location loc, @NotNull Material material, byte data); + public void sendBlockChange(Location loc, Material material, byte data); /** * Send a block change. This fakes a block change packet for a user at a @@ -934,7 +928,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param loc The location of the changed block * @param block The new block */ - public void sendBlockChange(@NotNull Location loc, @NotNull BlockData block); + public void sendBlockChange(Location loc, BlockData block); /** * Send a multi-block change. This fakes a block change packet for a user @@ -954,7 +948,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param blocks the block states to send to the player */ - public void sendBlockChanges(@NotNull Collection blocks); + public void sendBlockChanges(Collection blocks); /** * Send a multi-block change. This fakes a block change packet for a user @@ -979,7 +973,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * than 1.19.4 */ @Deprecated(since = "1.20") - public void sendBlockChanges(@NotNull Collection blocks, boolean suppressLightUpdates); + public void sendBlockChanges(Collection blocks, boolean suppressLightUpdates); /** * Send block damage. This fakes block break progress at a certain location @@ -990,7 +984,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param progress the progress from 0.0 - 1.0 where 0 is no damage and * 1.0 is the most damaged */ - public void sendBlockDamage(@NotNull Location loc, float progress); + public void sendBlockDamage(Location loc, float progress); // Paper start /** @@ -999,7 +993,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param blockChanges A map of the positions you want to change to their new block data */ - void sendMultiBlockChange(@NotNull Map blockChanges); + void sendMultiBlockChange(Map blockChanges); /** * Send multiple block changes. This fakes a multi block change packet for each @@ -1010,7 +1004,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated suppressLightUpdates is no longer available in 1.20+, use {@link #sendMultiBlockChange(Map)} */ @Deprecated - default void sendMultiBlockChange(@NotNull Map blockChanges, boolean suppressLightUpdates) { + default void sendMultiBlockChange(Map blockChanges, boolean suppressLightUpdates) { this.sendMultiBlockChange(blockChanges); } // Paper end @@ -1029,7 +1023,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * 1.0 is the most damaged * @param source the entity to which the damage belongs */ - public void sendBlockDamage(@NotNull Location loc, float progress, @NotNull Entity source); + public void sendBlockDamage(Location loc, float progress, Entity source); /** * Send block damage. This fakes block break progress at a certain location @@ -1046,7 +1040,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param sourceId the entity id of the entity to which the damage belongs. * Can be an id that does not associate directly with an existing or loaded entity. */ - public void sendBlockDamage(@NotNull Location loc, float progress, int sourceId); + public void sendBlockDamage(Location loc, float progress, int sourceId); /** * Send an equipment change for the target entity. This will not @@ -1057,7 +1051,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param item the item to which the slot should be changed, or null to set * it to air */ - public void sendEquipmentChange(@NotNull LivingEntity entity, @NotNull EquipmentSlot slot, @Nullable ItemStack item); + public void sendEquipmentChange(LivingEntity entity, EquipmentSlot slot, @Nullable ItemStack item); /** * Send multiple equipment changes for the target entity. This will not @@ -1067,7 +1061,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param items the slots to change, where the values are the items to which * the slot should be changed. null values will set the slot to air, empty map is not allowed */ - public void sendEquipmentChange(@NotNull LivingEntity entity, @NotNull Map items); + public void sendEquipmentChange(LivingEntity entity, Map items); // Paper start /** @@ -1089,7 +1083,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated - default void sendSignChange(@NotNull Location loc, @Nullable java.util.List lines) throws IllegalArgumentException { + default void sendSignChange(Location loc, java.util.@Nullable List lines) throws IllegalArgumentException { this.sendSignChange(loc, lines, DyeColor.BLACK); } @@ -1114,7 +1108,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated - default void sendSignChange(@NotNull Location loc, @Nullable java.util.List lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException { + default void sendSignChange(Location loc, java.util.@Nullable List lines, DyeColor dyeColor) throws IllegalArgumentException { this.sendSignChange(loc, lines, dyeColor, false); } @@ -1139,7 +1133,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated - default void sendSignChange(@NotNull Location loc, @Nullable java.util.List lines, boolean hasGlowingText) throws IllegalArgumentException { + default void sendSignChange(Location loc, java.util.@Nullable List lines, boolean hasGlowingText) throws IllegalArgumentException { this.sendSignChange(loc, lines, DyeColor.BLACK, hasGlowingText); } @@ -1165,7 +1159,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated - void sendSignChange(@NotNull Location loc, @Nullable java.util.List lines, @NotNull DyeColor dyeColor, boolean hasGlowingText) + void sendSignChange(Location loc, java.util.@Nullable List lines, DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; // Paper end @@ -1191,7 +1185,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated // Paper - public void sendSignChange(@NotNull Location loc, @Nullable String[] lines) throws IllegalArgumentException; + public void sendSignChange(Location loc, @Nullable String[] lines) throws IllegalArgumentException; /** * Send a sign change. This fakes a sign change packet for a user at @@ -1217,7 +1211,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated // Paper - public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException; + public void sendSignChange(Location loc, @Nullable String[] lines, DyeColor dyeColor) throws IllegalArgumentException; /** * Send a sign change. This fakes a sign change packet for a user at @@ -1244,7 +1238,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * (constructed e.g. via {@link Material#createBlockData()}) */ @Deprecated // Paper - public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; + public void sendSignChange(Location loc, @Nullable String[] lines, DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; /** * Send a TileState change. This fakes a TileState change for a user at @@ -1264,7 +1258,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException if tileState is null */ @ApiStatus.Experimental - public void sendBlockUpdate(@NotNull Location loc, @NotNull TileState tileState) throws IllegalArgumentException; + public void sendBlockUpdate(Location loc, TileState tileState) throws IllegalArgumentException; /** * Change a potion effect for the target entity. This will not actually @@ -1278,7 +1272,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param entity the entity whose potion effects to change * @param effect the effect to change */ - public void sendPotionEffectChange(@NotNull LivingEntity entity, @NotNull PotionEffect effect); + public void sendPotionEffectChange(LivingEntity entity, PotionEffect effect); /** * Remove a potion effect for the target entity. This will not actually @@ -1290,7 +1284,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param entity the entity whose potion effects to change * @param type the effect type to remove */ - public void sendPotionEffectChangeRemove(@NotNull LivingEntity entity, @NotNull PotionEffectType type); + public void sendPotionEffectChangeRemove(LivingEntity entity, PotionEffectType type); /** * Render a map and send it to the player in its entirety. This may be @@ -1298,7 +1292,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param map The map to be sent */ - public void sendMap(@NotNull MapView map); + public void sendMap(MapView map); // Paper start /** @@ -1350,9 +1344,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ // For reference, Bukkit defines this as nullable, while they impl isn't, we'll follow API. - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerFull(@Nullable String reason) { + public default org.bukkit.@Nullable BanEntry banPlayerFull(@Nullable String reason) { return banPlayerFull(reason, null, null); } @@ -1364,9 +1357,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerFull(@Nullable String reason, @Nullable String source) { + public default org.bukkit.@Nullable BanEntry banPlayerFull(@Nullable String reason, @Nullable String source) { return banPlayerFull(reason, null, source); } @@ -1378,9 +1370,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerFull(@Nullable String reason, @Nullable java.util.Date expires) { + public default org.bukkit.@Nullable BanEntry banPlayerFull(@Nullable String reason, java.util.@Nullable Date expires) { return banPlayerFull(reason, expires, null); } @@ -1393,9 +1384,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerFull(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source) { + public default org.bukkit.@Nullable BanEntry banPlayerFull(@Nullable String reason, java.util.@Nullable Date expires, @Nullable String source) { banPlayer(reason, expires, source); return banPlayerIP(reason, expires, source, true); } @@ -1409,9 +1399,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, boolean kickPlayer) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, boolean kickPlayer) { return banPlayerIP(reason, null, null, kickPlayer); } @@ -1424,9 +1413,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, @Nullable String source, boolean kickPlayer) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, @Nullable String source, boolean kickPlayer) { return banPlayerIP(reason, null, source, kickPlayer); } @@ -1439,9 +1427,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, @Nullable java.util.Date expires, boolean kickPlayer) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, java.util.@Nullable Date expires, boolean kickPlayer) { return banPlayerIP(reason, expires, null, kickPlayer); } @@ -1453,9 +1440,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason) { return banPlayerIP(reason, null, null); } @@ -1467,9 +1453,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, @Nullable String source) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, @Nullable String source) { return banPlayerIP(reason, null, source); } @@ -1481,9 +1466,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, @Nullable java.util.Date expires) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, java.util.@Nullable Date expires) { return banPlayerIP(reason, expires, null); } @@ -1496,9 +1480,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, java.util.@Nullable Date expires, @Nullable String source) { return banPlayerIP(reason, expires, source, true); } @@ -1512,9 +1495,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return Ban Entry * @deprecated use {@link #ban(String, Date, String)} and {@link #banIp(String, Date, String, boolean)} */ - @Nullable @Deprecated(since = "1.20.4") - public default org.bukkit.BanEntry banPlayerIP(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source, boolean kickPlayer) { + public default org.bukkit.@Nullable BanEntry banPlayerIP(@Nullable String reason, java.util.@Nullable Date expires, @Nullable String source, boolean kickPlayer) { org.bukkit.BanEntry banEntry = org.bukkit.Bukkit.getServer().getBanList(org.bukkit.BanList.Type.IP).addBan(getAddress().getAddress().getHostAddress(), reason, expires, source); if (kickPlayer && isOnline()) { getPlayer().kickPlayer(reason); @@ -1532,7 +1514,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)} */ @Deprecated - public void sendActionBar(@NotNull String message); + public void sendActionBar(String message); /** * Sends an Action Bar message to the client. @@ -1544,7 +1526,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)} */ @Deprecated - public void sendActionBar(char alternateChar, @NotNull String message); + public void sendActionBar(char alternateChar, String message); /** * Sends an Action Bar message to the client. @@ -1553,7 +1535,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #sendActionBar(net.kyori.adventure.text.Component)} */ @Deprecated - public void sendActionBar(@NotNull net.md_5.bungee.api.chat.BaseComponent... message); + public void sendActionBar(net.md_5.bungee.api.chat.BaseComponent... message); /** * Sends the component to the player @@ -1563,7 +1545,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ @Override @Deprecated - public default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) { + public default void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) { spigot().sendMessage(component); } @@ -1575,7 +1557,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ @Override @Deprecated - public default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) { + public default void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) { spigot().sendMessage(components); } @@ -1599,7 +1581,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)} */ @Deprecated - public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent[] header, @Nullable net.md_5.bungee.api.chat.BaseComponent[] footer); + public void setPlayerListHeaderFooter(net.md_5.bungee.api.chat.BaseComponent @Nullable [] header, net.md_5.bungee.api.chat.BaseComponent @Nullable [] footer); /** * Set the text displayed in the player list header and footer for this player @@ -1609,7 +1591,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)} */ @Deprecated - public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent header, @Nullable net.md_5.bungee.api.chat.BaseComponent footer); + public void setPlayerListHeaderFooter(net.md_5.bungee.api.chat.@Nullable BaseComponent header, net.md_5.bungee.api.chat.@Nullable BaseComponent footer); /** * Update the times for titles displayed to the player @@ -1647,7 +1629,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} */ @Deprecated - public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title); + public void showTitle(net.md_5.bungee.api.chat.@Nullable BaseComponent[] title); /** * Show the given title to the player, along with the last subtitle set, using the last set times @@ -1656,7 +1638,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} */ @Deprecated - public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title); + public void showTitle(net.md_5.bungee.api.chat.@Nullable BaseComponent title); /** * Show the given title and subtitle to the player using the given times @@ -1669,7 +1651,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} */ @Deprecated - public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title, @Nullable net.md_5.bungee.api.chat.BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); + public void showTitle(net.md_5.bungee.api.chat.@Nullable BaseComponent[] title, net.md_5.bungee.api.chat.@Nullable BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); /** * Show the given title and subtitle to the player using the given times @@ -1682,7 +1664,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} */ @Deprecated - public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title, @Nullable net.md_5.bungee.api.chat.BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); + public void showTitle(net.md_5.bungee.api.chat.@Nullable BaseComponent title, net.md_5.bungee.api.chat.@Nullable BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); /** * Show the title to the player, overriding any previously displayed title. @@ -1694,7 +1676,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} */ @Deprecated - void sendTitle(@NotNull com.destroystokyo.paper.Title title); + void sendTitle(com.destroystokyo.paper.Title title); /** * Show the title to the player, overriding any previously displayed title. @@ -1706,7 +1688,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} */ @Deprecated - void updateTitle(@NotNull com.destroystokyo.paper.Title title); + void updateTitle(com.destroystokyo.paper.Title title); /** * Hide any title that is currently visible to the player @@ -1732,7 +1714,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param links links to send */ - public void sendLinks(@NotNull ServerLinks links); + public void sendLinks(ServerLinks links); /** * Add custom chat completion suggestions shown to the player while typing a @@ -1740,7 +1722,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param completions the completions to send */ - public void addCustomChatCompletions(@NotNull Collection completions); + public void addCustomChatCompletions(Collection completions); /** * Remove custom chat completion suggestions shown to the player while @@ -1752,7 +1734,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param completions the completions to remove */ - public void removeCustomChatCompletions(@NotNull Collection completions); + public void removeCustomChatCompletions(Collection completions); /** * Set the list of chat completion suggestions shown to the player while @@ -1763,7 +1745,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param completions the completions to set */ - public void setCustomChatCompletions(@NotNull Collection completions); + public void setCustomChatCompletions(Collection completions); /** * Forces an update of the player's entire inventory. @@ -1835,7 +1817,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param type The WeatherType enum type the player should experience */ - public void setPlayerWeather(@NotNull WeatherType type); + public void setPlayerWeather(WeatherType type); /** * Returns the type of weather the player is currently experiencing. @@ -2047,14 +2029,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param flyingFallDamage Enables fall damage when {@link #getAllowFlight()} is {@code true} */ - public void setFlyingFallDamage(@NotNull net.kyori.adventure.util.TriState flyingFallDamage); + public void setFlyingFallDamage(net.kyori.adventure.util.TriState flyingFallDamage); /** * Allows you to get if fall damage is enabled while {@link #getAllowFlight()} is {@code true} * * @return A tristate of whether fall damage is enabled, not set, or disabled when {@link #getAllowFlight()} is {@code true} */ - @NotNull public net.kyori.adventure.util.TriState hasFlyingFallDamage(); // Paper end @@ -2065,7 +2046,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated see {@link #hidePlayer(Plugin, Player)} */ @Deprecated(since = "1.12.2") - public void hidePlayer(@NotNull Player player); + public void hidePlayer(Player player); /** * Hides a player from this player @@ -2073,7 +2054,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param plugin Plugin that wants to hide the player * @param player Player to hide */ - public void hidePlayer(@NotNull Plugin plugin, @NotNull Player player); + public void hidePlayer(Plugin plugin, Player player); /** * Allows this player to see a player that was previously hidden @@ -2082,7 +2063,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated see {@link #showPlayer(Plugin, Player)} */ @Deprecated(since = "1.12.2") - public void showPlayer(@NotNull Player player); + public void showPlayer(Player player); /** * Allows this player to see a player that was previously hidden. If @@ -2092,7 +2073,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param plugin Plugin that wants to show the player * @param player Player to show */ - public void showPlayer(@NotNull Plugin plugin, @NotNull Player player); + public void showPlayer(Plugin plugin, Player player); /** * Checks to see if a player has been hidden from this player @@ -2101,7 +2082,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return True if the provided player is not being hidden from this * player */ - public boolean canSee(@NotNull Player player); + public boolean canSee(Player player); /** * Visually hides an entity from this player. @@ -2109,7 +2090,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param plugin Plugin that wants to hide the entity * @param entity Entity to hide */ - public void hideEntity(@NotNull Plugin plugin, @NotNull Entity entity); + public void hideEntity(Plugin plugin, Entity entity); /** * Allows this player to see an entity that was previously hidden. If @@ -2119,7 +2100,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param plugin Plugin that wants to show the entity * @param entity Entity to show */ - public void showEntity(@NotNull Plugin plugin, @NotNull Entity entity); + public void showEntity(Plugin plugin, Entity entity); /** * Checks to see if an entity has been visually hidden from this player. @@ -2128,7 +2109,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return True if the provided entity is not being hidden from this * player */ - public boolean canSee(@NotNull Entity entity); + public boolean canSee(Entity entity); // Paper start /** @@ -2137,7 +2118,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param other The other {@link Player} to check for listing. * @return True if the {@code other} player is listed for {@code this}. */ - boolean isListed(@NotNull Player other); + boolean isListed(Player other); /** * Unlists the {@code other} player from the tablist. @@ -2145,7 +2126,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param other The other {@link Player} to de-list. * @return True if the {@code other} player was listed. */ - boolean unlistPlayer(@NotNull Player other); + boolean unlistPlayer(Player other); /** * Lists the {@code other} player. @@ -2153,7 +2134,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param other The other {@link Player} to list. * @return True if the {@code other} player was not listed. */ - boolean listPlayer(@NotNull Player other); + boolean listPlayer(Player other); // Paper end /** @@ -2235,7 +2216,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * should use {@link #setResourcePack(UUID, String, byte[], net.kyori.adventure.text.Component, boolean)}. */ @Deprecated(since = "1.7.2") - public void setTexturePack(@NotNull String url); + public void setTexturePack(String url); /** * Request that the player's client download and switch resource packs. @@ -2268,7 +2249,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)} */ @Deprecated // Paper - adventure - public void setResourcePack(@NotNull String url); + public void setResourcePack(String url); /** * Request that the player's client download and switch resource packs. @@ -2310,7 +2291,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * long. */ @Deprecated // Paper - adventure - public void setResourcePack(@NotNull String url, byte @Nullable [] hash); + public void setResourcePack(String url, byte @Nullable [] hash); /** * Request that the player's client download and switch resource packs. @@ -2355,7 +2336,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * long. */ @Deprecated // Paper - adventure - public void setResourcePack(@NotNull String url, byte @Nullable [] hash, @Nullable String prompt); + public void setResourcePack(String url, byte @Nullable [] hash, @Nullable String prompt); // Paper start /** @@ -2400,7 +2381,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * long. * @see #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest) */ - default void setResourcePack(final @NotNull String url, final byte @Nullable [] hash, final net.kyori.adventure.text.@Nullable Component prompt) { + default void setResourcePack(final String url, final byte @Nullable [] hash, final net.kyori.adventure.text.@Nullable Component prompt) { this.setResourcePack(url, hash, prompt, false); } // Paper end @@ -2449,7 +2430,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)} */ @Deprecated // Paper - adventure - public void setResourcePack(@NotNull String url, byte @Nullable [] hash, boolean force); + public void setResourcePack(String url, byte @Nullable [] hash, boolean force); /** * Request that the player's client download and switch resource packs. @@ -2496,7 +2477,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)} */ @Deprecated // Paper - public void setResourcePack(@NotNull String url, byte @Nullable [] hash, @Nullable String prompt, boolean force); + public void setResourcePack(String url, byte @Nullable [] hash, @Nullable String prompt, boolean force); // Paper start /** @@ -2543,7 +2524,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * long. * @see #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest) */ - default void setResourcePack(final @NotNull String url, final byte @Nullable [] hash, final net.kyori.adventure.text.@Nullable Component prompt, final boolean force) { + default void setResourcePack(final String url, final byte @Nullable [] hash, final net.kyori.adventure.text.@Nullable Component prompt, final boolean force) { this.setResourcePack(UUID.nameUUIDFromBytes(url.getBytes(java.nio.charset.StandardCharsets.UTF_8)), url, hash, prompt, force); } // Paper end @@ -2594,7 +2575,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)} */ @Deprecated // Paper - adventure - public void setResourcePack(@NotNull UUID id, @NotNull String url, byte @Nullable [] hash, @Nullable String prompt, boolean force); + public void setResourcePack(UUID id, String url, byte @Nullable [] hash, @Nullable String prompt, boolean force); // Paper start /** @@ -2642,7 +2623,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * long. * @see #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest) */ - void setResourcePack(@NotNull UUID uuid, @NotNull String url, byte @Nullable [] hash, net.kyori.adventure.text.@Nullable Component prompt, boolean force); + void setResourcePack(UUID uuid, String url, byte @Nullable [] hash, net.kyori.adventure.text.@Nullable Component prompt, boolean force); // Paper end // Paper start - more resource pack API @@ -2675,7 +2656,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is too long. The * length restriction is an implementation specific arbitrary value. */ - default void setResourcePack(final @NotNull String url, final @NotNull String hash) { + default void setResourcePack(final String url, final String hash) { this.setResourcePack(url, hash, false); } @@ -2709,7 +2690,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is too long. The * length restriction is an implementation specific arbitrary value. */ - default void setResourcePack(final @NotNull String url, final @NotNull String hash, final boolean required) { + default void setResourcePack(final String url, final String hash, final boolean required) { this.setResourcePack(url, hash, required, null); } @@ -2744,7 +2725,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is too long. The * length restriction is an implementation specific arbitrary value. */ - default void setResourcePack(final @NotNull String url, final @NotNull String hash, final boolean required, final net.kyori.adventure.text.@Nullable Component resourcePackPrompt) { + default void setResourcePack(final String url, final String hash, final boolean required, final net.kyori.adventure.text.@Nullable Component resourcePackPrompt) { this.setResourcePack(UUID.nameUUIDFromBytes(url.getBytes(java.nio.charset.StandardCharsets.UTF_8)), url, hash, resourcePackPrompt, required); } @@ -2780,7 +2761,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the URL is too long. The * length restriction is an implementation specific arbitrary value. */ - default void setResourcePack(final @NotNull UUID uuid, final @NotNull String url, final @NotNull String hash, final net.kyori.adventure.text.@Nullable Component resourcePackPrompt, final boolean required) { + default void setResourcePack(final UUID uuid, final String url, final String hash, final net.kyori.adventure.text.@Nullable Component resourcePackPrompt, final boolean required) { this.sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest.resourcePackRequest() .required(required) .replace(true) @@ -2863,7 +2844,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException Thrown if the hash is not 20 bytes * long. */ - public void addResourcePack(@NotNull UUID id, @NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force); + public void addResourcePack(UUID id, String url, @Nullable byte[] hash, @Nullable String prompt, boolean force); /** * Request that the player's client remove a resource pack sent by the @@ -2873,7 +2854,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalArgumentException If the ID is null. * @see #removeResourcePacks(UUID, UUID...) */ - public void removeResourcePack(@NotNull UUID id); + public void removeResourcePack(UUID id); /** * Request that the player's client remove all loaded resource pack sent by @@ -2887,7 +2868,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return The current scoreboard seen by this player */ - @NotNull public Scoreboard getScoreboard(); /** @@ -2900,7 +2880,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @throws IllegalStateException if this is a player that is not logged * yet or has logged out */ - public void setScoreboard(@NotNull Scoreboard scoreboard) throws IllegalArgumentException, IllegalStateException; + public void setScoreboard(Scoreboard scoreboard) throws IllegalArgumentException, IllegalStateException; /** * Gets the {@link WorldBorder} visible to this Player, or null if viewing @@ -3054,7 +3034,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param location the location to spawn at * @param count the number of particles */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count); + public void spawnParticle(Particle particle, Location location, int count); /** * Spawns the particle (the number of times specified by count) @@ -3066,7 +3046,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param z the position on the z axis to spawn at * @param count the number of particles */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count); + public void spawnParticle(Particle particle, double x, double y, double z, int count); /** * Spawns the particle (the number of times specified by count) @@ -3079,7 +3059,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param data the data to use for the particle or null, * the type of this depends on {@link Particle#getDataType()} */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, @Nullable T data); + public void spawnParticle(Particle particle, Location location, int count, @Nullable T data); /** @@ -3095,7 +3075,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param data the data to use for the particle or null, * the type of this depends on {@link Particle#getDataType()} */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, @Nullable T data); + public void spawnParticle(Particle particle, double x, double y, double z, int count, @Nullable T data); /** * Spawns the particle (the number of times specified by count) @@ -3110,7 +3090,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param offsetY the maximum random offset on the Y axis * @param offsetZ the maximum random offset on the Z axis */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ); + public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, double offsetZ); /** * Spawns the particle (the number of times specified by count) @@ -3127,7 +3107,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param offsetY the maximum random offset on the Y axis * @param offsetZ the maximum random offset on the Z axis */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ); + public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ); /** * Spawns the particle (the number of times specified by count) @@ -3145,7 +3125,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param data the data to use for the particle or null, * the type of this depends on {@link Particle#getDataType()} */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, @Nullable T data); + public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, double offsetZ, @Nullable T data); /** * Spawns the particle (the number of times specified by count) @@ -3165,7 +3145,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param data the data to use for the particle or null, * the type of this depends on {@link Particle#getDataType()} */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, @Nullable T data); + public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, @Nullable T data); /** * Spawns the particle (the number of times specified by count) @@ -3182,7 +3162,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param extra the extra data for this particle, depends on the * particle used (normally speed) */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra); + public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra); /** * Spawns the particle (the number of times specified by count) @@ -3201,7 +3181,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param extra the extra data for this particle, depends on the * particle used (normally speed) */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra); + public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra); /** * Spawns the particle (the number of times specified by count) @@ -3221,7 +3201,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param data the data to use for the particle or null, * the type of this depends on {@link Particle#getDataType()} */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data); + public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data); /** * Spawns the particle (the number of times specified by count) @@ -3243,7 +3223,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param data the data to use for the particle or null, * the type of this depends on {@link Particle#getDataType()} */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data); + public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data); /** * Spawns the particle (the number of times specified by count) @@ -3266,7 +3246,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * range and encourage their client to render it regardless of * settings */ - public void spawnParticle(@NotNull Particle particle, @NotNull Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data, boolean force); + public void spawnParticle(Particle particle, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data, boolean force); /** * Spawns the particle (the number of times specified by count) @@ -3291,7 +3271,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * range and encourage their client to render it regardless of * settings */ - public void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data, boolean force); + public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data, boolean force); /** * Return the player's progression on the specified advancement. @@ -3299,8 +3279,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param advancement advancement * @return object detailing the player's progress */ - @NotNull - public AdvancementProgress getAdvancementProgress(@NotNull Advancement advancement); + public AdvancementProgress getAdvancementProgress(Advancement advancement); /** * Get the player's current client side view distance. @@ -3318,7 +3297,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return the player's locale */ - @NotNull java.util.Locale locale(); + java.util.Locale locale(); // Paper end /** * Gets the player's estimated ping in milliseconds. @@ -3347,7 +3326,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return the player's locale * @deprecated in favour of {@link #locale()} */ - @NotNull @Deprecated // Paper public String getLocale(); @@ -3456,7 +3434,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param book The book to open for this player */ - public void openBook(@NotNull ItemStack book); + public void openBook(ItemStack book); /** * Open a Sign for editing by the Player. @@ -3467,7 +3445,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #openSign(Sign, Side)} */ @Deprecated - public void openSign(@NotNull Sign sign); + public void openSign(Sign sign); /** * Open a Sign for editing by the Player. @@ -3477,7 +3455,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param sign The sign to edit * @param side The side to edit */ - public void openSign(@NotNull Sign sign, @NotNull Side side); + public void openSign(Sign sign, Side side); /** * Shows the demo screen to the player, this screen is normally only seen in @@ -3495,9 +3473,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public boolean isAllowingServerListings(); // Paper start - @NotNull @Override - default net.kyori.adventure.text.event.HoverEvent asHoverEvent(final @NotNull java.util.function.UnaryOperator op) { + default net.kyori.adventure.text.event.HoverEvent asHoverEvent(final java.util.function.UnaryOperator op) { return net.kyori.adventure.text.event.HoverEvent.showEntity(op.apply(net.kyori.adventure.text.event.HoverEvent.ShowEntity.of(this.getType().getKey(), this.getUniqueId(), this.displayName()))); } // Paper end @@ -3508,7 +3485,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return The players profile object */ - com.destroystokyo.paper.profile.@NotNull PlayerProfile getPlayerProfile(); + com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile(); /** * Changes the PlayerProfile for this player. This will cause this player @@ -3519,7 +3496,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @param profile The new profile to use */ - void setPlayerProfile(com.destroystokyo.paper.profile.@NotNull PlayerProfile profile); + void setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile profile); // Paper end - Player Profile API // Paper start - attack cooldown API @@ -3548,7 +3525,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM /** * @return the client option value of the player */ - @NotNull T getClientOption(com.destroystokyo.paper.@NotNull ClientOption option); + T getClientOption(com.destroystokyo.paper.ClientOption option); // Paper end - client option API // Paper start - elytra boost API @@ -3564,7 +3541,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link HumanEntity#fireworkBoost(ItemStack)} instead. Note that this method does not * check if the player is gliding or not. */ - default @Nullable Firework boostElytra(final @NotNull ItemStack firework) { + default @Nullable Firework boostElytra(final ItemStack firework) { com.google.common.base.Preconditions.checkState(this.isGliding(), "Player must be gliding"); return this.fireworkBoost(firework); } @@ -3592,7 +3569,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #addCustomChatCompletions(Collection)} */ @Deprecated(since = "1.20.1") - void addAdditionalChatCompletions(@NotNull java.util.Collection completions); + void addAdditionalChatCompletions(java.util.Collection completions); /** * Removes custom chat completion suggestions that the client @@ -3605,7 +3582,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@link #addCustomChatCompletions(Collection)} */ @Deprecated(since = "1.20.1") - void removeAdditionalChatCompletions(@NotNull java.util.Collection completions); + void removeAdditionalChatCompletions(java.util.Collection completions); // Paper end - custom chat completions API // Spigot start @@ -3617,7 +3594,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return the player's connection address */ - @NotNull public InetSocketAddress getRawAddress() { throw new UnsupportedOperationException("Not supported yet."); } @@ -3634,20 +3610,19 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return a Set with all hidden players */ - @NotNull public java.util.Set getHiddenPlayers() { throw new UnsupportedOperationException("Not supported yet."); } @Deprecated // Paper @Override - public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) { + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } @Deprecated // Paper @Override - public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) { + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); } @@ -3659,7 +3634,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component} */ @Deprecated // Paper - public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @NotNull net.md_5.bungee.api.chat.BaseComponent component) { + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } @@ -3671,7 +3646,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component} */ @Deprecated // Paper - public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) { + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); } @@ -3684,7 +3659,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component} */ @Deprecated // Paper - public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @Nullable java.util.UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent component) { + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, java.util.@Nullable UUID sender, net.md_5.bungee.api.chat.BaseComponent component) { throw new UnsupportedOperationException("Not supported yet."); } @@ -3697,7 +3672,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component} */ @Deprecated // Paper - public void sendMessage(@NotNull net.md_5.bungee.api.ChatMessageType position, @Nullable java.util.UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) { + public void sendMessage(net.md_5.bungee.api.ChatMessageType position, java.util.@Nullable UUID sender, net.md_5.bungee.api.chat.BaseComponent... components) { throw new UnsupportedOperationException("Not supported yet."); } @@ -3740,7 +3715,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param playerAnchor What part of the player should face the entity * @param entityAnchor What part of the entity the player should face */ - void lookAt(@NotNull org.bukkit.entity.Entity entity, @NotNull LookAnchor playerAnchor, @NotNull LookAnchor entityAnchor); + void lookAt(org.bukkit.entity.Entity entity, LookAnchor playerAnchor, LookAnchor entityAnchor); // Paper end - Teleport API // Paper start @@ -3824,7 +3799,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * * @return the current idle duration of this player */ - @NotNull Duration getIdleDuration(); + Duration getIdleDuration(); /** * Resets this player's idle duration. @@ -3846,7 +3821,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * vs it potentially being an unmodifiable view of the set chunks. */ @ApiStatus.Experimental - java.util.@NotNull @org.jetbrains.annotations.Unmodifiable Set getSentChunkKeys(); + java.util.@org.jetbrains.annotations.Unmodifiable Set getSentChunkKeys(); /** * Gets the set of chunks that have been sent to the player. @@ -3856,7 +3831,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * vs it potentially being an unmodifiable view of the set chunks. */ @ApiStatus.Experimental - java.util.@NotNull @org.jetbrains.annotations.Unmodifiable Set getSentChunks(); + java.util.@org.jetbrains.annotations.Unmodifiable Set getSentChunks(); /** * Checks if the player has been sent a specific chunk. @@ -3864,7 +3839,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param chunk the chunk to check * @return true if the player has been sent the chunk, false otherwise */ - default boolean isChunkSent(@NotNull org.bukkit.Chunk chunk) { + default boolean isChunkSent(org.bukkit.Chunk chunk) { return this.isChunkSent(chunk.getChunkKey()); } @@ -3878,7 +3853,6 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM boolean isChunkSent(long chunkKey); // Paper end - @NotNull @Override Spigot spigot(); // Spigot end @@ -3892,7 +3866,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param effect the entity effect * @param target the target entity */ - void sendEntityEffect(org.bukkit.@NotNull EntityEffect effect, @NotNull Entity target); + void sendEntityEffect(org.bukkit.EntityEffect effect, Entity target); // Paper end - entity effect API /** @@ -3903,7 +3877,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param items the items to give. * @return the result of this method, holding leftovers and spawned items. */ - default @NotNull PlayerGiveResult give(@NotNull final ItemStack @NotNull ... items) { + default PlayerGiveResult give(final ItemStack ... items) { return this.give(List.of(items)); } @@ -3915,7 +3889,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param items the items to give * @return the result of this method, holding leftovers and spawned items. */ - default @NotNull PlayerGiveResult give(@NotNull final Collection<@NotNull ItemStack> items) { + default PlayerGiveResult give(final Collection items) { return this.give(items, true); } @@ -3927,5 +3901,5 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * did not fit the inventory * @return the result of this method, holding leftovers and spawned items. */ - @NotNull PlayerGiveResult give(@NotNull Collection<@NotNull ItemStack> items, boolean dropIfFull); + PlayerGiveResult give(Collection items, boolean dropIfFull); } From 1a04e96ab7095f9c0ea45d39b7448401c5ae5ee2 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Feb 2025 20:59:13 +0100 Subject: [PATCH 094/203] Fix EntityBreedEvent cancellation (#12046) --- .../ai/behavior/VillagerMakeLove.java.patch | 2 +- .../world/entity/animal/Animal.java.patch | 26 ++++++++-------- .../world/entity/animal/Fox.java.patch | 31 +++++++++---------- .../craftbukkit/event/CraftEventFactory.java | 4 +-- 4 files changed, 30 insertions(+), 33 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch index 303c80235..592af079e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/VillagerMakeLove.java.patch @@ -17,7 +17,7 @@ + parent.setAge(6000); + partner.setAge(6000); + level.addFreshEntityWithPassengers(breedOffspring, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); -+ // CraftBukkit end ++ // CraftBukkit end - call EntityBreedEvent level.broadcastEntityEvent(breedOffspring, (byte)12); return Optional.of(breedOffspring); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch index 47de92435..f837f2d73 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch @@ -63,7 +63,7 @@ this.level().broadcastEntityEvent(this, (byte)18); } -@@ -220,23 +_,45 @@ +@@ -220,23 +_,44 @@ if (breedOffspring != null) { breedOffspring.setBaby(true); breedOffspring.moveTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); @@ -74,43 +74,43 @@ + int experience = this.getRandom().nextInt(7) + 1; + org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(breedOffspring, this, mate, breeder, this.breedItem, experience); + if (entityBreedEvent.isCancelled()) { ++ this.resetLove(); ++ mate.resetLove(); + return; + } + experience = entityBreedEvent.getExperience(); + this.finalizeSpawnChildFromBreeding(level, mate, breedOffspring, experience); + level.addFreshEntityWithPassengers(breedOffspring, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); -+ // CraftBukkit end ++ // CraftBukkit end - call EntityBreedEvent } } public void finalizeSpawnChildFromBreeding(ServerLevel level, Animal animal, @Nullable AgeableMob baby) { - Optional.ofNullable(this.getLoveCause()).or(() -> Optional.ofNullable(animal.getLoveCause())).ifPresent(player -> { -+ // CraftBukkit start ++ // CraftBukkit start - call EntityBreedEvent + this.finalizeSpawnChildFromBreeding(level, animal, baby, this.getRandom().nextInt(7) + 1); + } ++ + public void finalizeSpawnChildFromBreeding(ServerLevel level, Animal animal, @Nullable AgeableMob baby, int experience) { -+ // CraftBukkit end -+ // Paper start ++ // CraftBukkit end - call EntityBreedEvent ++ // Paper start - call EntityBreedEvent + ServerPlayer player = this.getLoveCause(); + if (player == null) player = animal.getLoveCause(); + if (player != null) { -+ // Paper end ++ // Paper end - call EntityBreedEvent player.awardStat(Stats.ANIMALS_BRED); CriteriaTriggers.BRED_ANIMALS.trigger(player, this, animal, baby); - }); -+ } // Paper ++ } // Paper - call EntityBreedEvent this.setAge(6000); animal.setAge(6000); this.resetLove(); animal.resetLove(); level.broadcastEntityEvent(this, (byte)18); - if (level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { +- if (level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1)); -+ // CraftBukkit start - use event experience -+ if (experience > 0) { -+ level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, player, baby)); // Paper -+ } -+ // CraftBukkit end ++ if (experience > 0 && level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - call EntityBreedEvent ++ level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, player, baby)); // Paper - call EntityBreedEvent, add spawn context } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch index aa6fdd965..e2b7f5326 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch @@ -93,7 +93,7 @@ } public static boolean isPathClear(Fox fox, LivingEntity livingEntity) { -@@ -853,6 +_,14 @@ +@@ -853,6 +_,18 @@ if (loveCause1 != null && loveCause != loveCause1) { fox.addTrustedUUID(loveCause1.getUUID()); } @@ -102,13 +102,17 @@ + fox.moveTo(this.animal.getX(), this.animal.getY(), this.animal.getZ(), 0.0F, 0.0F); + int experience = this.animal.getRandom().nextInt(7) + 1; + org.bukkit.event.entity.EntityBreedEvent entityBreedEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreedEvent(fox, this.animal, this.partner, loveCause, this.animal.breedItem, experience); -+ if (entityBreedEvent.isCancelled()) return; ++ if (entityBreedEvent.isCancelled()) { ++ this.animal.resetLove(); ++ this.partner.resetLove(); ++ return; ++ } + experience = entityBreedEvent.getExperience(); -+ // CraftBukkit end ++ // CraftBukkit end - call EntityBreedEvent if (serverPlayer != null) { serverPlayer.awardStat(Stats.ANIMALS_BRED); -@@ -863,15 +_,17 @@ +@@ -863,14 +_,12 @@ this.partner.setAge(6000); this.animal.resetLove(); this.partner.resetLove(); @@ -117,22 +121,15 @@ - serverLevel.addFreshEntityWithPassengers(fox); + serverLevel.addFreshEntityWithPassengers(fox, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason this.level.broadcastEntityEvent(this.animal, (byte)18); - if (serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { -- this.level -- .addFreshEntity( +- if (serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { ++ if (experience > 0 && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - call EntityBreedEvent + this.level + .addFreshEntity( - new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1) -- ); -+ // CraftBukkit start - use event experience -+ if (experience > 0) { -+ this.level -+ .addFreshEntity( -+ new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper -+ ); -+ } -+ // CraftBukkit end ++ new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper - call EntityBreedEvent, add spawn context + ); } } - } @@ -934,6 +_,7 @@ private void pickSweetBerries(BlockState state) { int ageValue = state.getValue(SweetBerryBushBlock.AGE); 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 85adadf7d..fd4c1d67c 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 @@ -1896,11 +1896,11 @@ public class CraftEventFactory { } public static EntityBreedEvent callEntityBreedEvent(net.minecraft.world.entity.LivingEntity child, net.minecraft.world.entity.LivingEntity mother, net.minecraft.world.entity.LivingEntity father, net.minecraft.world.entity.LivingEntity breeder, ItemStack bredWith, int experience) { - org.bukkit.entity.LivingEntity breederEntity = (LivingEntity) (breeder == null ? null : breeder.getBukkitEntity()); + LivingEntity breederEntity = breeder == null ? null : (LivingEntity) breeder.getBukkitEntity(); CraftItemStack bredWithStack = bredWith == null ? null : CraftItemStack.asCraftMirror(bredWith).clone(); EntityBreedEvent event = new EntityBreedEvent((LivingEntity) child.getBukkitEntity(), (LivingEntity) mother.getBukkitEntity(), (LivingEntity) father.getBukkitEntity(), breederEntity, bredWithStack, experience); - child.level().getCraftServer().getPluginManager().callEvent(event); + event.callEvent(); return event; } From eff617b8f886d81b91d74b9b0ee9951375e73425 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Feb 2025 22:10:08 +0100 Subject: [PATCH 095/203] [ci skip] Deprecate Server#setSpawnRadius (#12024) --- paper-api/src/main/java/org/bukkit/Bukkit.java | 4 ++++ paper-api/src/main/java/org/bukkit/Server.java | 4 ++++ .../java/org/bukkit/craftbukkit/CraftServer.java | 12 +----------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Bukkit.java b/paper-api/src/main/java/org/bukkit/Bukkit.java index 9196b1e62..9764489c0 100644 --- a/paper-api/src/main/java/org/bukkit/Bukkit.java +++ b/paper-api/src/main/java/org/bukkit/Bukkit.java @@ -1373,7 +1373,11 @@ public final class Bukkit { * Sets the radius, in blocks, around each worlds spawn point to protect. * * @param value new spawn radius, or 0 if none + * @deprecated has not functioned for a long time as the spawn radius is defined by the server.properties file. + * There is no API replacement for this method. It is generally recommended to implement "protection"-like behaviour + * via events or third-party plugin APIs. */ + @Deprecated(since = "1.21.4", forRemoval = true) public static void setSpawnRadius(int value) { server.setSpawnRadius(value); } diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index 11923ef0e..fa6f9d505 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -1219,7 +1219,11 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * Sets the radius, in blocks, around each worlds spawn point to protect. * * @param value new spawn radius, or 0 if none + * @deprecated has not functioned for a long time as the spawn radius is defined by the server.properties file. + * There is no API replacement for this method. It is generally recommended to implement "protection"-like behaviour + * via events or third-party plugin APIs. */ + @Deprecated(since = "1.21.4", forRemoval = true) public void setSpawnRadius(int value); /** 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 d2de78996..d162c9c57 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1864,22 +1864,12 @@ public final class CraftServer implements Server { return result; } - public void removeBukkitSpawnRadius() { - this.configuration.set("settings.spawn-radius", null); - this.saveConfig(); - } - - public int getBukkitSpawnRadius() { - return this.configuration.getInt("settings.spawn-radius", -1); - } - - // Paper start @Override public net.kyori.adventure.text.Component shutdownMessage() { String msg = getShutdownMessage(); return msg != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(msg) : null; } - // Paper end + @Override @Deprecated // Paper public String getShutdownMessage() { From edacfdf4624735d093413e64b4efd192f72d844e Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 9 Feb 2025 11:51:11 +0100 Subject: [PATCH 096/203] Do not queue player info packets (#12080) Player info packets carry chat state to other clients since the introduction of chat signatures. Queuing these packets while force pushing chat packets allows for potentially inverted packet order, which may cause chain corruption on clients. --- ...imize-Network-Manager-and-add-advanced-packet-sup.patch | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 02589fdaa..ca477fbd3 100644 --- a/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -28,7 +28,7 @@ and then catch exceptions and close if they fire. Part of this commit was authored by: Spottedleaf, sandtechnology diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..ad8f8428b75e37097487cdfbd0db2421ee4cbe37 100644 +index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c022d913d 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -85,7 +85,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -232,7 +232,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..ad8f8428b75e37097487cdfbd0db2421 // Paper start - Add PlayerConnectionCloseEvent if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) { /* Player was logged in, either game listener or configuration listener */ -@@ -797,4 +888,93 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -797,4 +888,96 @@ public class Connection extends SimpleChannelInboundHandler> { public void setBandwidthLogger(LocalSampleLogger bandwithLogger) { this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwithLogger); } @@ -280,6 +280,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..ad8f8428b75e37097487cdfbd0db2421 + packet instanceof net.minecraft.network.protocol.common.ClientboundKeepAlivePacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundSystemChatPacket || ++ packet instanceof net.minecraft.network.protocol.game.ClientboundDisguisedChatPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundCommandSuggestionsPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundSetTitleTextPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundSetSubtitleTextPacket || @@ -290,6 +291,8 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..ad8f8428b75e37097487cdfbd0db2421 + packet instanceof net.minecraft.network.protocol.game.ClientboundSoundEntityPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundStopSoundPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket || ++ packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket || ++ packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundBossEventPacket; + } + } From cafef9ce9bb73cbcb9bc9c59eb982ae2516f5ee6 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Mon, 10 Feb 2025 07:34:52 -0500 Subject: [PATCH 097/203] [ci skip] Move EntityUtil to correct directory (#12092) --- .../0016-Moonrise-optimisation-patches.patch | 54 +------------------ .../moonrise/common/util/EntityUtil.java | 44 +++++++++++++++ 2 files changed, 46 insertions(+), 52 deletions(-) create mode 100644 paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index de786f06e..95220d300 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -27976,7 +27976,7 @@ index 4eb040006f5d41b47e5ac9df5d9f19c4315d6343..7fa41dea184b01891f45d8e404bc1cba this.generatingStep = generatingStep; this.cache = cache; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index ff0315cffdb282fdc0a1ffd15e2954caa76835c9..5e94dd9e26aa4fd6545dbaae2ae0cb51cb6f13e0 100644 +index 5d88b2790710a885957ffcffc02fb99c917123c5..7d1d4abfb04829d8c4722e326c6c6b8fb2ab91f4 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -1312,7 +1312,7 @@ public abstract class PlayerList { @@ -28372,7 +28372,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 55e0bd63a65867f4e496ec0b188ccba7a4a8ebef..161c7a53427917fdbd328401a84a7cab703701a8 100644 +index 449c43286e1483b69667c626b234529a16c19ee1..b268b428ec8f2e50737e1dd5cc705c537322433c 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -35961,53 +35961,3 @@ index 5b6bd88a5bbbce6cce351938418eba4326e41002..faf45ac459f7c25309d6ef6dce371d48 int i = -this.pendingTicks.size(); for (SavedTick savedTick : this.pendingTicks) { -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java b/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java -new file mode 100644 -index 0000000000000000000000000000000000000000..db5805298d33fbde3f3ed23d706dbc6af814122d ---- /dev/null -+++ b/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java -@@ -0,0 +1,44 @@ -+package ca.spottedleaf.moonrise.common.util; -+ -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.phys.Vec3; -+import java.text.DecimalFormat; -+import java.util.ArrayList; -+import java.util.List; -+ -+public final class EntityUtil { -+ -+ private static final ThreadLocal THREE_DECIMAL_PLACES = ThreadLocal.withInitial(() -> { -+ return new DecimalFormat("#,##0.000"); -+ }); -+ -+ private static String formatVec(final Vec3 vec) { -+ final DecimalFormat format = THREE_DECIMAL_PLACES.get(); -+ -+ return "(" + format.format(vec.x) + "," + format.format(vec.y) + "," + format.format(vec.z) + ")"; -+ } -+ -+ private static String dumpEntityWithoutReferences(final Entity entity) { -+ if (entity == null) { -+ return "{null}"; -+ } -+ -+ return "{type=" + entity.getClass().getSimpleName() + ",id=" + entity.getId() + ",uuid=" + entity.getUUID() + ",pos=" + formatVec(entity.position()) -+ + ",mot=" + formatVec(entity.getDeltaMovement()) + ",aabb=" + entity.getBoundingBox() + ",removed=" + entity.getRemovalReason() + ",has_vehicle=" + (entity.getVehicle() != null) -+ + ",passenger_count=" + entity.getPassengers().size(); -+ } -+ -+ public static String dumpEntity(final Entity entity) { -+ final List passengers = entity.getPassengers(); -+ final List passengerStrings = new ArrayList<>(passengers.size()); -+ -+ for (final Entity passenger : passengers) { -+ passengerStrings.add("(" + dumpEntityWithoutReferences(passenger) + ")"); -+ } -+ -+ return "{root=[" + dumpEntityWithoutReferences(entity) + "], vehicle=[" + dumpEntityWithoutReferences(entity.getVehicle()) -+ + "], passengers=[" + String.join(",", passengerStrings) + "]"; -+ } -+ -+ private EntityUtil() {} -+} diff --git a/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java new file mode 100644 index 000000000..db5805298 --- /dev/null +++ b/paper-server/src/main/java/ca/spottedleaf/moonrise/common/util/EntityUtil.java @@ -0,0 +1,44 @@ +package ca.spottedleaf.moonrise.common.util; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; + +public final class EntityUtil { + + private static final ThreadLocal THREE_DECIMAL_PLACES = ThreadLocal.withInitial(() -> { + return new DecimalFormat("#,##0.000"); + }); + + private static String formatVec(final Vec3 vec) { + final DecimalFormat format = THREE_DECIMAL_PLACES.get(); + + return "(" + format.format(vec.x) + "," + format.format(vec.y) + "," + format.format(vec.z) + ")"; + } + + private static String dumpEntityWithoutReferences(final Entity entity) { + if (entity == null) { + return "{null}"; + } + + return "{type=" + entity.getClass().getSimpleName() + ",id=" + entity.getId() + ",uuid=" + entity.getUUID() + ",pos=" + formatVec(entity.position()) + + ",mot=" + formatVec(entity.getDeltaMovement()) + ",aabb=" + entity.getBoundingBox() + ",removed=" + entity.getRemovalReason() + ",has_vehicle=" + (entity.getVehicle() != null) + + ",passenger_count=" + entity.getPassengers().size(); + } + + public static String dumpEntity(final Entity entity) { + final List passengers = entity.getPassengers(); + final List passengerStrings = new ArrayList<>(passengers.size()); + + for (final Entity passenger : passengers) { + passengerStrings.add("(" + dumpEntityWithoutReferences(passenger) + ")"); + } + + return "{root=[" + dumpEntityWithoutReferences(entity) + "], vehicle=[" + dumpEntityWithoutReferences(entity.getVehicle()) + + "], passengers=[" + String.join(",", passengerStrings) + "]"; + } + + private EntityUtil() {} +} From fa5824e4c86f59c0740796f045fb2c8514cfac9f Mon Sep 17 00:00:00 2001 From: Owen <23108066+Owen1212055@users.noreply.github.com> Date: Mon, 10 Feb 2025 17:04:38 -0500 Subject: [PATCH 098/203] Add skipTripwireHookPlacementValidation (#12091) This allows for the configuration of tripwire hook duping. --- .../minecraft/world/level/block/TripWireHookBlock.java.patch | 2 +- .../io/papermc/paper/configuration/GlobalConfiguration.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch index 225f53b41..b2b90b416 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch @@ -53,7 +53,7 @@ + if (!cancelledEmitterHook) { // Paper - Call BlockRedstoneEvent emitState(level, pos, flag2, flag3, flag, flag1); if (!attaching) { -+ if (level.getBlockState(pos).is(Blocks.TRIPWIRE_HOOK)) // Paper - Validate tripwire hook placement before update ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.skipTripwireHookPlacementValidation || level.getBlockState(pos).is(Blocks.TRIPWIRE_HOOK)) // Paper - Validate tripwire hook placement before update level.setBlock(pos, blockState1.setValue(FACING, direction), 3); if (shouldNotifyNeighbours) { notifyNeighbors(block, level, pos, direction); 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 bacd1d90a..42777adb0 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 @@ -171,6 +171,8 @@ public class GlobalConfiguration extends ConfigurationPart { public class UnsupportedSettings extends ConfigurationPart { @Comment("This setting allows for exploits related to end portals, for example sand duping") public boolean allowUnsafeEndPortalTeleportation = false; + @Comment("This setting controls the ability to enable dupes related to tripwires.") + public boolean skipTripwireHookPlacementValidation = false; @Comment("This setting controls if players should be able to break bedrock, end portals and other intended to be permanent blocks.") public boolean allowPermanentBlockBreakExploits = false; @Comment("This setting controls if player should be able to use TNT duplication, but this also allows duplicating carpet, rails and potentially other items") From 3bd69f2e5699230894963252bed2d168fc3b8247 Mon Sep 17 00:00:00 2001 From: David <54660361+NonSwag@users.noreply.github.com> Date: Mon, 10 Feb 2025 23:07:46 +0100 Subject: [PATCH 099/203] [ci skip] Enhance javadoc for World#setAutoSave method (#12088) Clarify that disabling auto-save does not stop all saving operations. This addition explicitly mentions that the world will still save on shutdown and explains the intended purpose of the method. --- paper-api/src/main/java/org/bukkit/World.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index 8784842d1..2729f71ac 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -2781,6 +2781,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * * @param value true if the world should automatically save, otherwise * false + * @apiNote This does not disable saving entirely, the world will still be saved on shutdown.
+ * The intended use of this method is to disable the periodical autosave by the game. */ public void setAutoSave(boolean value); From 13c80a5eb3fe1f393e572e6211a8b64f2d9227d0 Mon Sep 17 00:00:00 2001 From: aerulion Date: Wed, 12 Feb 2025 11:06:42 +0100 Subject: [PATCH 100/203] [ci skip] Fix PlayerShearBlockEvent javadoc typos (#12101) --- .../io/papermc/paper/event/block/PlayerShearBlockEvent.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java b/paper-api/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java index 33c6e1868..42c6ad962 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/block/PlayerShearBlockEvent.java @@ -12,10 +12,10 @@ import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** - * Called when a player uses sheers on a block. + * Called when a player uses shears on a block. *

- * This event is not called when breaking blocks with shears but instead only when a - * player uses the sheer item on a block to garner drops from said block and/or change its state. + * This event is not called when a player breaks blocks with shears, but rather when a + * player uses the shears on a block to collect drops from it and/or modify its state. *

* Examples include shearing a pumpkin to turn it into a carved pumpkin or shearing a beehive to get honeycomb. */ From db2aa1803dc8cf887968d9acdf3fe0489cb90907 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Wed, 12 Feb 2025 07:16:40 -0300 Subject: [PATCH 101/203] [ci skip] Fix incomplete example in javadocs for PreFlattenTagRegistrar (#12102) --- .../main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java b/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java index 8d8a00e4d..7c00ad45f 100644 --- a/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java +++ b/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java @@ -22,6 +22,8 @@ import org.jspecify.annotations.NullMarked; *

{@code
  * class YourBootstrapClass implements PluginBootstrap {
  *
+ *     public static final TagKey AXE_PICKAXE = TagKey.create(RegistryKey.ITEM, Key.key("papermc:axe_pickaxe"));
+ *
  *     @Override
  *     public void bootstrap(BootstrapContext context) {
  *         LifecycleEventManager manager = context.getLifecycleManager();

From cf7c6c74835153fc467b998395edda1ab2211312 Mon Sep 17 00:00:00 2001
From: Pedro <3602279+Doc94@users.noreply.github.com>
Date: Wed, 12 Feb 2025 07:27:13 -0300
Subject: [PATCH 102/203] [ci skip] Fix incomplete example in javadocs for
 PostFlattenTagRegistrar (#12103)

---
 .../java/io/papermc/paper/tag/PostFlattenTagRegistrar.java    | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java b/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java
index 22db9446c..909abcb18 100644
--- a/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java
+++ b/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java
@@ -23,6 +23,8 @@ import org.jspecify.annotations.NullMarked;
  * 
{@code
  * class YourBootstrapClass implements PluginBootstrap {
  *
+ *     public static final TypedKey CUSTOM_POINTY_ENCHANT = EnchantmentKeys.create(Key.key("papermc:pointy"));
+ *
  *     @Override
  *     public void bootstrap(BootstrapContext context) {
  *         LifecycleEventManager manager = context.getLifecycleManager();
@@ -30,7 +32,7 @@ import org.jspecify.annotations.NullMarked;
  *             final PostFlattenTagRegistrar registrar = event.registrar();
  *             registrar.addToTag(
  *                 EnchantmentTagKeys.IN_ENCHANTING_TABLE,
- *                 Set.of(CUSTOM_ENCHANT)
+ *                 Set.of(CUSTOM_POINTY_ENCHANT)
  *             );
  *         });
  *     }

From 072a8317b264a9cc6c1303b50889f2218257c89c Mon Sep 17 00:00:00 2001
From: Tamion <70228790+notTamion@users.noreply.github.com>
Date: Wed, 12 Feb 2025 23:13:07 +0100
Subject: [PATCH 103/203] Add proper attached blocks API to AbstractArrow
 (#12099)

---
 .../java/org/bukkit/entity/AbstractArrow.java | 15 +++++++++++++++
 .../projectile/AbstractArrow.java.patch       | 10 +++++++++-
 .../entity/CraftAbstractArrow.java            | 19 ++++++++++++++-----
 3 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java b/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java
index e63353ff7..1c2c9ed0d 100644
--- a/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java
+++ b/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java
@@ -5,6 +5,8 @@ import org.bukkit.inventory.ItemStack;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.Unmodifiable;
+import java.util.List;
 
 /**
  * Represents an arrow.
@@ -99,10 +101,23 @@ public interface AbstractArrow extends Projectile {
      * Gets the block to which this arrow is attached.
      *
      * @return the attached block or null if not attached
+     * @deprecated can be attached to multiple blocks use {@link AbstractArrow#getAttachedBlocks()} instead
      */
     @Nullable
+    @Deprecated(since = "1.21.4")
     public Block getAttachedBlock();
 
+    /**
+     * Gets the block(s) which this arrow is attached to.
+     * All the returned blocks are responsible for preventing
+     * the arrow from falling.
+     *
+     * @return the attached block(s) or an empty list if not attached
+     */
+    @NotNull
+    @Unmodifiable
+    List getAttachedBlocks();
+
     /**
      * Gets the current pickup status of this arrow.
      *
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch
index cf61cc49d..6bb662ba7 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch
@@ -77,7 +77,7 @@
                  this.hasImpulse = true;
                  if (this.getPierceLevel() > 0 && projectileDeflection == ProjectileDeflection.NONE) {
                      continue;
-@@ -313,6 +_,19 @@
+@@ -313,13 +_,26 @@
          }
      }
  
@@ -97,6 +97,14 @@
      @Override
      protected double getDefaultGravity() {
          return 0.05;
+     }
+ 
+     private boolean shouldFall() {
+-        return this.isInGround() && this.level().noCollision(new AABB(this.position(), this.position()).inflate(0.06));
++        return this.isInGround() && this.level().noCollision(new AABB(this.position(), this.position()).inflate(0.06)); // Paper - getAttachedBlocks api; diff on change
+     }
+ 
+     private void startFalling() {
 @@ -329,7 +_,7 @@
          this.life = 0;
      }
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 af2c1ad8c..66db4132b 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
@@ -1,15 +1,20 @@
 package org.bukkit.craftbukkit.entity;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 import net.minecraft.core.BlockPos;
+import net.minecraft.world.entity.Entity;
 import net.minecraft.world.item.Items;
+import net.minecraft.world.level.BlockCollisions;
+import net.minecraft.world.phys.AABB;
 import org.bukkit.block.Block;
 import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.craftbukkit.block.CraftBlock;
 import org.bukkit.craftbukkit.inventory.CraftItemStack;
 import org.bukkit.entity.AbstractArrow;
-import org.bukkit.entity.Entity;
 import org.bukkit.inventory.ItemStack;
-import org.bukkit.projectiles.ProjectileSource;
+import java.util.List;
 
 public class CraftAbstractArrow extends AbstractProjectile implements AbstractArrow {
 
@@ -68,12 +73,16 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
 
     @Override
     public Block getAttachedBlock() {
+        return Iterables.getFirst(getAttachedBlocks(), null);
+    }
+
+    @Override
+    public List getAttachedBlocks() {
         if (!this.isInBlock()) {
-            return null;
+            return ImmutableList.of();
         }
 
-        BlockPos pos = this.getHandle().blockPosition();
-        return this.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+        return ImmutableList.copyOf(new BlockCollisions<>(this.getHandle().level(), (Entity) null, new AABB(this.getHandle().position(), this.getHandle().position()).inflate(0.06), false, (mutableBlockPos, voxelShape) -> CraftBlock.at(this.getHandle().level(), mutableBlockPos)));
     }
 
     @Override

From 1be2e5f311f3acb526261dca31cdde43259e8608 Mon Sep 17 00:00:00 2001
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
Date: Wed, 12 Feb 2025 23:13:34 +0100
Subject: [PATCH 104/203] Fix vanilla map decorations sending when not dirty
 (#12098)

---
 .../world/level/saveddata/maps/MapItemSavedData.java.patch      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 9aa3e5536..8e832c66a 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
@@ -193,7 +193,7 @@
  
              Collection collection;
 -            if (this.dirtyDecorations && this.tick++ % 5 == 0) {
-+            if ((true || this.dirtyDecorations) && this.tick++ % 5 == 0) { // CraftBukkit - custom maps don't update this yet // TODO fix this
++            if ((!vanillaMaps || this.dirtyDecorations) && this.tick++ % 5 == 0) { // Paper - bypass dirtyDecorations for custom maps
                  this.dirtyDecorations = false;
 -                collection = MapItemSavedData.this.decorations.values();
 +                // CraftBukkit start

From a06179a0182066d928de62cdcd9f6a7da16d1cd2 Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Wed, 12 Feb 2025 23:14:07 +0100
Subject: [PATCH 105/203] Update entity effect (#12104)

---
 .../main/java/org/bukkit/EntityEffect.java    | 264 ++++++++++++------
 .../src/main/java/org/bukkit/Particle.java    |   3 -
 .../main/java/org/bukkit/entity/Entity.java   |   4 +-
 .../craftbukkit/entity/CraftEntity.java       |   9 +-
 .../craftbukkit/entity/CraftPlayer.java       |   6 +-
 5 files changed, 196 insertions(+), 90 deletions(-)

diff --git a/paper-api/src/main/java/org/bukkit/EntityEffect.java b/paper-api/src/main/java/org/bukkit/EntityEffect.java
index 37c321067..35641226d 100644
--- a/paper-api/src/main/java/org/bukkit/EntityEffect.java
+++ b/paper-api/src/main/java/org/bukkit/EntityEffect.java
@@ -1,9 +1,14 @@
 package org.bukkit;
 
 import com.google.common.base.Preconditions;
-import org.bukkit.entity.Ageable;
+import io.papermc.paper.datacomponent.DataComponentTypes;
+import org.bukkit.entity.Allay;
+import org.bukkit.entity.Animals;
+import org.bukkit.entity.Armadillo;
 import org.bukkit.entity.ArmorStand;
+import org.bukkit.entity.Arrow;
 import org.bukkit.entity.Cat;
+import org.bukkit.entity.Creaking;
 import org.bukkit.entity.Dolphin;
 import org.bukkit.entity.Egg;
 import org.bukkit.entity.Entity;
@@ -15,6 +20,8 @@ import org.bukkit.entity.Guardian;
 import org.bukkit.entity.Hoglin;
 import org.bukkit.entity.IronGolem;
 import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Mob;
+import org.bukkit.entity.Ocelot;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Rabbit;
 import org.bukkit.entity.Ravager;
@@ -23,7 +30,6 @@ import org.bukkit.entity.Sniffer;
 import org.bukkit.entity.Snowball;
 import org.bukkit.entity.Squid;
 import org.bukkit.entity.Tameable;
-import org.bukkit.entity.TippedArrow;
 import org.bukkit.entity.Villager;
 import org.bukkit.entity.Warden;
 import org.bukkit.entity.Witch;
@@ -32,32 +38,34 @@ import org.bukkit.entity.Zoglin;
 import org.bukkit.entity.ZombieVillager;
 import org.bukkit.entity.minecart.ExplosiveMinecart;
 import org.bukkit.entity.minecart.SpawnerMinecart;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
+import java.util.Set;
 
 /**
- * A list of all Effects that can happen to entities.
+ * A list of all effects that can happen to entities.
  */
 public enum EntityEffect {
 
     /**
-     * Colored particles from a tipped arrow.
+     * Colored particles from an arrow.
      */
-    ARROW_PARTICLES(0, TippedArrow.class),
+    ARROW_PARTICLES(0, Arrow.class),
     /**
      * Rabbit jumping.
      */
     RABBIT_JUMP(1, Rabbit.class),
     /**
-     * Resets a spawner minecart's delay to 200. Does not effect actual spawning
-     * delay, only the speed at which the entity in the spawner spins
+     * Resets a spawner minecart's delay to 200. Does not affect actual spawning
+     * delay, only the speed at which the entity in the spawner spins.
      */
     RESET_SPAWNER_MINECART_DELAY(1, SpawnerMinecart.class),
     /**
      * When mobs get hurt.
      *
-     * @deprecated Use {@link LivingEntity#playHurtAnimation(float)}
+     * @deprecated use {@link LivingEntity#playHurtAnimation(float)}
      */
-    @Deprecated(since = "1.20.1")
+    @Deprecated(since = "1.20.1", forRemoval = true)
     HURT(2, LivingEntity.class),
     /**
      * When a mob dies.
@@ -65,58 +73,97 @@ public enum EntityEffect {
      * This will cause client-glitches!
      *
      * @deprecated split into individual effects
-     * @see #EGG_BREAK
-     * @see #SNOWBALL_BREAK
+     * @see #PROJECTILE_CRACK
      * @see #ENTITY_DEATH
      */
-    @Deprecated(since = "1.12.2")
+    @Deprecated(since = "1.12.2", forRemoval = true)
     DEATH(3, Entity.class),
     /**
-     * Spawns the egg breaking particles
+     * Spawns the egg breaking particles.
+     *
+     * @deprecated use {@link #PROJECTILE_CRACK}
      */
+    @Deprecated(since = "1.21.4", forRemoval = true)
     EGG_BREAK(3, Egg.class),
     /**
-     * Spawns the snowball breaking particles
+     * Spawns the snowball breaking particles.
+     *
+     * @deprecated use {@link #PROJECTILE_CRACK}
      */
+    @Deprecated(since = "1.21.4", forRemoval = true)
     SNOWBALL_BREAK(3, Snowball.class),
     /**
-     * Plays the entity death sound and animation
+     * Shows the crack particles when a projectile
+     * hits something.
+     */
+    PROJECTILE_CRACK(3, Egg.class, Snowball.class),
+    /**
+     * Plays the entity death sound and animation.
      * 

* This will cause client-glitches! */ ENTITY_DEATH(3, LivingEntity.class), /** - * Plays the fang attack animation + * Plays the evoker's fang attack animation. + * + * @deprecated use {@link #ENTITY_ATTACK} */ + @Deprecated(since = "1.21.4", forRemoval = true) FANG_ATTACK(4, EvokerFangs.class), /** - * Plays the hoglin attack animation + * Plays the hoglin attack animation. + * + * @deprecated use {@link #ENTITY_ATTACK} */ + @Deprecated(since = "1.21.4", forRemoval = true) HOGLIN_ATTACK(4, Hoglin.class), /** - * Plays the iron golem attack animation + * Plays the iron golem attack animation. + * + * @deprecated use {@link #ENTITY_ATTACK} */ + @Deprecated(since = "1.21.4", forRemoval = true) IRON_GOLEN_ATTACK(4, IronGolem.class), /** - * Plays the ravager attack animation + * Plays the ravager attack animation. + * + * @deprecated use {@link #ENTITY_ATTACK} */ + @Deprecated(since = "1.21.4", forRemoval = true) RAVAGER_ATTACK(4, Ravager.class), /** - * Plays the warden attack animation + * Plays the warden attack animation. + * + * @deprecated use {@link #ENTITY_ATTACK} */ + @Deprecated(since = "1.21.4", forRemoval = true) WARDEN_ATTACK(4, Warden.class), /** - * Plays the zoglin attack animation + * Plays the zoglin attack animation. + * + * @deprecated use {@link #ENTITY_ATTACK} */ + @Deprecated(since = "1.21.4", forRemoval = true) ZOGLIN_ATTACK(4, Zoglin.class), + /** + * Plays an attack animation for the respective entities. + */ + ENTITY_ATTACK(4, EvokerFangs.class, Hoglin.class, IronGolem.class, Ravager.class, Warden.class, Zoglin.class, Creaking.class), // 5 - unused /** * The smoke when taming an entity fails. + * * @deprecated use {@link EntityEffect#TAMING_FAILED} */ - @Deprecated(since = "1.21") // Paper + @Deprecated(since = "1.21", forRemoval = true) WOLF_SMOKE(6, Tameable.class), - // Paper start - rename "wolf" effects + /** + * The hearts when taming an entity succeeds. + * + * @deprecated use {@link EntityEffect#TAMING_SUCCEEDED} + */ + @Deprecated(since = "1.21", forRemoval = true) + WOLF_HEARTS(7, Tameable.class), /** * The smoke when taming an entity fails. */ @@ -125,20 +172,13 @@ public enum EntityEffect { * The hearts when taming an entity succeeds. */ TAMING_SUCCEEDED(7, Tameable.class), - // Paper end - rename "wolf" effects - /** - * The hearts when taming an entity succeeds. - * @deprecated use {@link EntityEffect#TAMING_SUCCEEDED} - */ - @Deprecated(since = "1.21") // Paper - WOLF_HEARTS(7, Tameable.class), /** * When a wolf shakes (after being wet). * * @see EntityEffect#WOLF_SHAKE_STOP */ WOLF_SHAKE(8, Wolf.class), - // 9 - unused + // 9 - internal /** * When an entity eats a LONG_GRASS block. * @@ -146,10 +186,10 @@ public enum EntityEffect { * @see #SHEEP_EAT_GRASS * @see #TNT_MINECART_IGNITE */ - @Deprecated(since = "1.12.2") + @Deprecated(since = "1.12.2", forRemoval = true) SHEEP_EAT(10, Entity.class), /** - * Plays the sheep eating grass animation + * Plays the sheep eating grass animation. */ SHEEP_EAT_GRASS(10, Sheep.class), /** @@ -179,7 +219,8 @@ public enum EntityEffect { */ WITCH_MAGIC(15, Witch.class), /** - * When a zombie transforms into a villager by shaking violently. + * Plays the sound when a zombie villager is + * cured. */ ZOMBIE_TRANSFORM(16, ZombieVillager.class), /** @@ -187,9 +228,10 @@ public enum EntityEffect { */ FIREWORK_EXPLODE(17, Firework.class), /** - * Hearts from a breeding entity. + * Hearts from a breeding entity + * or when an Allay duplicates. */ - LOVE_HEARTS(18, Ageable.class), + LOVE_HEARTS(18, Animals.class, Allay.class), /** * Resets squid rotation. */ @@ -197,7 +239,7 @@ public enum EntityEffect { /** * Silverfish entering block, spawner spawning. */ - ENTITY_POOF(20, LivingEntity.class), + ENTITY_POOF(20, Mob.class), /** * Guardian plays the attack sound effect. */ @@ -218,9 +260,10 @@ public enum EntityEffect { ARMOR_STAND_HIT(32, ArmorStand.class), /** * Entity hurt by thorns attack. + * * @deprecated in favor of {@link LivingEntity#playHurtAnimation(float)} or {@link Entity#broadcastHurtAnimation(java.util.Collection)} */ - @Deprecated(since = "1.19.4", forRemoval = true) // Paper + @Deprecated(since = "1.19.4", forRemoval = true) THORNS_HURT(33, LivingEntity.class), /** * Iron golem puts away rose. @@ -228,16 +271,27 @@ public enum EntityEffect { IRON_GOLEM_SHEATH(34, IronGolem.class), /** * Totem prevents entity death. + * + * @deprecated see {@link #PROTECTED_FROM_DEATH} */ + @Deprecated(since = "1.21.2", forRemoval = true) TOTEM_RESURRECT(35, LivingEntity.class), + /** + * Item with {@link DataComponentTypes#DEATH_PROTECTION} prevents entity death. + * For player, the item selected will be shown for a moment on the screen, if the + * item is not found a totem will appear. + */ + PROTECTED_FROM_DEATH(35, Entity.class), /** * Entity hurt due to drowning damage. + * * @deprecated in favor of {@link LivingEntity#playHurtAnimation(float)} or {@link Entity#broadcastHurtAnimation(java.util.Collection)} */ @Deprecated(since = "1.19.4", forRemoval = true) HURT_DROWN(36, LivingEntity.class), /** * Entity hurt due to explosion damage. + * * @deprecated in favor of {@link LivingEntity#playHurtAnimation(float)} or {@link Entity#broadcastHurtAnimation(java.util.Collection)} */ @Deprecated(since = "1.19.4", forRemoval = true) @@ -252,66 +306,94 @@ public enum EntityEffect { RAVAGER_STUNNED(39, Ravager.class), /** * Cat taming failed. + * + * @deprecated use {@link #TRUSTING_FAILED} */ + @Deprecated(since = "1.14", forRemoval = true) CAT_TAME_FAIL(40, Cat.class), /** * Cat taming succeeded. + * + * @deprecated use {@link #TRUSTING_SUCCEEDED} */ + @Deprecated(since = "1.14", forRemoval = true) CAT_TAME_SUCCESS(41, Cat.class), + /** + * Ocelot trusting failed. + */ + TRUSTING_FAILED(40, Ocelot.class), + /** + * Ocelot trusting succeeded. + */ + TRUSTING_SUCCEEDED(41, Ocelot.class), /** * Villager splashes particles during a raid. */ VILLAGER_SPLASH(42, Villager.class), /** * Player's bad omen effect removed to start or increase raid difficult. + * * @deprecated raid system was overhauled in 1.20.5 */ @Deprecated(since = "1.20.5", forRemoval = true) PLAYER_BAD_OMEN_RAID(43, Player.class), /** * Entity hurt due to berry bush. Prickly! + * * @deprecated in favor of {@link LivingEntity#playHurtAnimation(float)} or {@link Entity#broadcastHurtAnimation(java.util.Collection)} */ @Deprecated(since = "1.19.4", forRemoval = true) HURT_BERRY_BUSH(44, LivingEntity.class), /** - * Fox chews the food in its mouth + * Fox chews the food in its mouth. */ FOX_CHEW(45, Fox.class), /** - * Entity teleported as a result of chorus fruit or as an enderman + * Entity teleported as a result of chorus fruit or as an enderman. */ TELEPORT_ENDER(46, LivingEntity.class), /** - * Entity breaks item in main hand + * Entity breaks item in main hand. + * + * @see org.bukkit.inventory.EquipmentSlot#HAND */ BREAK_EQUIPMENT_MAIN_HAND(47, LivingEntity.class), /** - * Entity breaks item in off hand + * Entity breaks item in off hand. + * + * @see org.bukkit.inventory.EquipmentSlot#OFF_HAND */ BREAK_EQUIPMENT_OFF_HAND(48, LivingEntity.class), /** - * Entity breaks item in helmet slot + * Entity breaks item in helmet slot. + * + * @see org.bukkit.inventory.EquipmentSlot#HEAD */ BREAK_EQUIPMENT_HELMET(49, LivingEntity.class), /** - * Entity breaks item in chestplate slot + * Entity breaks item in chestplate slot. + * + * @see org.bukkit.inventory.EquipmentSlot#CHEST */ BREAK_EQUIPMENT_CHESTPLATE(50, LivingEntity.class), /** - * Entity breaks item in legging slot + * Entity breaks item in legging slot. + * + * @see org.bukkit.inventory.EquipmentSlot#LEGS */ BREAK_EQUIPMENT_LEGGINGS(51, LivingEntity.class), /** - * Entity breaks item in boot slot + * Entity breaks item in boot slot. + * + * @see org.bukkit.inventory.EquipmentSlot#FEET */ BREAK_EQUIPMENT_BOOTS(52, LivingEntity.class), /** - * Spawns honey block slide particles at the entity's feet + * Spawns honey block slide particles at the entity's feet. */ HONEY_BLOCK_SLIDE_PARTICLES(53, Entity.class), /** - * Spawns honey block fall particles at the entity's feet + * Spawns honey block fall particles at the entity's feet. */ HONEY_BLOCK_FALL_PARTICLES(54, LivingEntity.class), /** @@ -319,110 +401,136 @@ public enum EntityEffect { */ SWAP_HAND_ITEMS(55, LivingEntity.class), /** - * Stops a wolf that is currently shaking + * Stops a wolf that is currently shaking. * * @see EntityEffect#WOLF_SHAKE */ WOLF_SHAKE_STOP(56, Wolf.class), // 57 - unused /** - * Goat lowers its head for ramming + * Goat lowers its head for ramming. * * @see #GOAT_RAISE_HEAD */ GOAT_LOWER_HEAD(58, Goat.class), /** - * Goat raises its head + * Goat raises its head. * * @see #GOAT_LOWER_HEAD */ GOAT_RAISE_HEAD(59, Goat.class), /** - * Spawns death smoke particles + * Spawns death smoke particles. */ SPAWN_DEATH_SMOKE(60, LivingEntity.class), /** - * Warden shakes its tendrils + * Warden shakes its tendrils. */ WARDEN_TENDRIL_SHAKE(61, Warden.class), /** - * Warden performs sonic attack animation
- * Does not play the sound or fire the beam + * Warden performs sonic attack animation. + *
+ * Does not play the sound or fire the beam. */ WARDEN_SONIC_ATTACK(62, Warden.class), /** - * Plays sniffer digging sound
+ * Plays sniffer digging sound. + *
* Sniffer must have a target and be in {@link Sniffer.State#SEARCHING} or - * {@link Sniffer.State#DIGGING} + * {@link Sniffer.State#DIGGING}. */ SNIFFER_DIG(63, Sniffer.class), - // Paper start - add missing EntityEffect /** * Armadillo peeks out of its shell */ - ARMADILLO_PEEK(64, org.bukkit.entity.Armadillo.class), + ARMADILLO_PEEK(64, Armadillo.class), /** - * {@link org.bukkit.inventory.EquipmentSlot#BODY} armor piece breaks + * {@link org.bukkit.inventory.EquipmentSlot#BODY} armor piece breaks. + * + * @deprecated use {@link #BREAK_EQUIPMENT_BODY} */ + @Deprecated(since = "1.21.4", forRemoval = true) BODY_BREAK(65, LivingEntity.class), + /** + * Entity breaks item in body slot. + * + * @see org.bukkit.inventory.EquipmentSlot#BODY + */ + BREAK_EQUIPMENT_BODY(65, LivingEntity.class), /** * A creaking transient shaking when being hit. * Does not apply to plain creaking entities as they are not invulnerable like the transient ones spawned by the * creaking heart. */ - SHAKE(66, org.bukkit.entity.Creaking.class); - // Paper end - add missing EntityEffect + SHAKE(66, Creaking.class); private final byte data; - private final Class applicable; + private final Set> applicableClasses; - EntityEffect(final int data, /*@NotNull*/ Class clazz) { + EntityEffect(int data, Class... applicableClasses) { + Preconditions.checkState(applicableClasses.length > 0, "Unknown applicable classes"); this.data = (byte) data; - this.applicable = clazz; + this.applicableClasses = Set.of(applicableClasses); } /** - * Gets the data value of this EntityEffect, may not be unique. + * Gets the data value of this entity effect, may not be unique. * - * @return The data value - * @apiNote Internal Use Only + * @return the data value */ - @org.jetbrains.annotations.ApiStatus.Internal // Paper + @ApiStatus.Internal public byte getData() { - return data; + return this.data; } /** - * Gets entity superclass which this affect is applicable to. + * Gets entity superclass which this entity effect is applicable to. * * @return applicable class + * @deprecated an entity effect can apply to multiple superclasses, see {@link #getApplicableClasses()} */ @NotNull + @Deprecated(since = "1.21.4") public Class getApplicable() { - return applicable; + return this.applicableClasses.iterator().next(); } /** - * Checks if this effect is applicable to the given entity. + * Gets the entity superclasses which this entity effect is applicable to. + * + * @return the applicable classes + */ + @NotNull + public Set> getApplicableClasses() { + return this.applicableClasses; + } + + /** + * Checks if this entity effect is applicable to the given entity. * * @param entity the entity to check - * @return true if applicable + * @return {@code true} if applicable */ public boolean isApplicableTo(@NotNull Entity entity) { Preconditions.checkArgument(entity != null, "Entity cannot be null"); - return isApplicableTo(entity.getClass()); + return this.isApplicableTo(entity.getClass()); } /** - * Checks if this effect is applicable to the given entity class. + * Checks if this entity effect is applicable to the given entity class. * * @param clazz the entity class to check - * @return true if applicable + * @return {@code true} if applicable */ public boolean isApplicableTo(@NotNull Class clazz) { Preconditions.checkArgument(clazz != null, "Class cannot be null"); - return applicable.isAssignableFrom(clazz); + for (Class applicableClass : this.applicableClasses) { + if (applicableClass.isAssignableFrom(clazz)) { + return true; + } + } + return false; } } diff --git a/paper-api/src/main/java/org/bukkit/Particle.java b/paper-api/src/main/java/org/bukkit/Particle.java index ddbcd977e..31c368934 100644 --- a/paper-api/src/main/java/org/bukkit/Particle.java +++ b/paper-api/src/main/java/org/bukkit/Particle.java @@ -146,12 +146,10 @@ public enum Particle implements Keyed { /** * Uses {@link BlockData} as DataType */ - @ApiStatus.Experimental BLOCK_CRUMBLE("block_crumble", BlockData.class), /** * Uses {@link Trail} as DataType */ - @ApiStatus.Experimental TRAIL("trail", Trail.class), OMINOUS_SPAWNING("ominous_spawning"), RAID_OMEN("raid_omen"), @@ -276,7 +274,6 @@ public enum Particle implements Keyed { /** * Options which can be applied to trail particles - a location, color and duration. */ - @ApiStatus.Experimental public static class Trail { private final Location target; 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 ddf7829ee..1dac39dec 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Entity.java +++ b/paper-api/src/main/java/org/bukkit/entity/Entity.java @@ -580,9 +580,9 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent *

* If the effect is not applicable to this class of entity, it will not play. * - * @param type Effect to play. + * @param effect Effect to play. */ - public void playEffect(@NotNull EntityEffect type); + public void playEffect(@NotNull EntityEffect effect); /** * Get the type of the entity. 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 659f0f9c7..f8762064e 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 @@ -544,13 +544,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } @Override - public void playEffect(EntityEffect type) { - Preconditions.checkArgument(type != null, "Type cannot be null"); + public void playEffect(EntityEffect effect) { + Preconditions.checkArgument(effect != null, "Entity effect cannot be null"); Preconditions.checkState(!this.entity.generation, "Cannot play effect during world generation"); + Preconditions.checkArgument(effect.isApplicableTo(this), "Entity effect cannot apply to this entity"); - if (type.getApplicable().isInstance(this)) { - this.getHandle().level().broadcastEntityEvent(this.getHandle(), type.getData()); - } + this.getHandle().level().broadcastEntityEvent(this.getHandle(), effect.getData()); } @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 baffa0360..3260f20b6 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 @@ -120,6 +120,7 @@ import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.DyeColor; import org.bukkit.Effect; +import org.bukkit.EntityEffect; import org.bukkit.GameMode; import org.bukkit.Input; import org.bukkit.Instrument; @@ -3543,10 +3544,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { // Paper start - entity effect API @Override - public void sendEntityEffect(final org.bukkit.EntityEffect effect, final org.bukkit.entity.Entity target) { - if (this.getHandle().connection == null || !effect.isApplicableTo(target)) { + public void sendEntityEffect(final EntityEffect effect, final org.bukkit.entity.Entity target) { + if (this.getHandle().connection == null) { return; } + Preconditions.checkArgument(effect.isApplicableTo(target), "Entity effect cannot apply to the target"); this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundEntityEventPacket(((CraftEntity) target).getHandle(), effect.getData())); } // Paper end - entity effect API From e616498ed7bb56a25eb1fca50ecc8007b7a66686 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:15:22 +0100 Subject: [PATCH 106/203] Add Vault block API (#12068) --- build-data/paper.at | 5 + .../src/main/java/org/bukkit/block/Vault.java | 179 +++++++++++++++++- .../entity/vault/VaultServerData.java.patch | 40 ++++ .../bukkit/craftbukkit/block/CraftVault.java | 138 +++++++++++++- 4 files changed, 360 insertions(+), 2 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultServerData.java.patch diff --git a/build-data/paper.at b/build-data/paper.at index cf91314d9..8e27f7157 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -628,6 +628,11 @@ public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner stateAcc public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData currentMobs public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData detectedPlayers public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextSpawnData +public net.minecraft.world.level.block.entity.vault.VaultBlockEntity serverData +public net.minecraft.world.level.block.entity.vault.VaultServerData getRewardedPlayers()Ljava/util/Set; +public net.minecraft.world.level.block.entity.vault.VaultServerData pauseStateUpdatingUntil(J)V +public net.minecraft.world.level.block.entity.vault.VaultServerData stateUpdatingResumesAt()J +public net.minecraft.world.level.block.entity.vault.VaultSharedData getConnectedPlayers()Ljava/util/Set; public net.minecraft.world.level.block.state.BlockBehaviour getMenuProvider(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/MenuProvider; public net.minecraft.world.level.block.state.BlockBehaviour hasCollision public net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase destroySpeed diff --git a/paper-api/src/main/java/org/bukkit/block/Vault.java b/paper-api/src/main/java/org/bukkit/block/Vault.java index 64c7b432c..6963f2969 100644 --- a/paper-api/src/main/java/org/bukkit/block/Vault.java +++ b/paper-api/src/main/java/org/bukkit/block/Vault.java @@ -1,7 +1,184 @@ package org.bukkit.block; +import org.bukkit.World; +import org.bukkit.inventory.ItemStack; +import org.bukkit.loot.LootTable; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import java.util.Collection; +import java.util.Set; +import java.util.UUID; + /** - * Represents a captured state of a trial spawner. + * Represents a captured state of a vault. */ +@NullMarked public interface Vault extends TileState { + /** + * Gets the range in blocks at which this vault will become active when a player is near. + * + * @return This vault's activation range. + */ + double getActivationRange(); + + /** + * Sets the range in blocks at which the vault will become active when a player is near. + * + * @param activationRange The new activation range. + * @throws IllegalArgumentException if the new range is not a number, or if the new range is more than {@link #getDeactivationRange()}. + */ + void setActivationRange(double activationRange); + + /** + * Gets the range in blocks at which this vault will become inactive when a player is not near. + * + * @return This vault's deactivation range. + */ + double getDeactivationRange(); + + /** + * Sets the range in blocks at which this vault will become inactive when a player is not near. + * + * @param deactivationRange The new deactivation range + * @throws IllegalArgumentException if the new range is not a number, or if the new range is less than {@link #getActivationRange()}. + */ + void setDeactivationRange(double deactivationRange); + + /** + * Gets the {@link ItemStack} that players must use to unlock this vault. + * + * @return The item that players must use to unlock this vault. + */ + ItemStack getKeyItem(); + + /** + * Sets the {@link ItemStack} that players must use to unlock this vault. + * + * @param key The key item. + */ + void setKeyItem(ItemStack key); + + /** + * Gets the {@link LootTable} that this vault will select rewards from. + * + * @return The loot table. + */ + LootTable getLootTable(); + + /** + * Sets the {@link LootTable} that this vault will select rewards from. + * + * @param lootTable The new loot table. + */ + void setLootTable(LootTable lootTable); + + /** + * Gets the loot table that this vault will display items from. + *

+ * Falls back to the regular {@link #getLootTable() loot table} if unset. + * + * @return The {@link LootTable} that will be used to display items. + */ + @Nullable + LootTable getDisplayedLootTable(); + + /** + * Sets the loot table that this vault will display items from. + * + * @param lootTable The new loot table to display, or {@code null} to clear this display override. + */ + void setDisplayedLootTable(@Nullable LootTable lootTable); + + /** + * Gets the next time (in {@link World#getGameTime() game time}) that this vault block will be updated/ticked at. + * + * @return The next time that this vault block will be updated/ticked at. + * @see World#getGameTime() + */ + long getNextStateUpdateTime(); + + /** + * Sets the next time that this vault block will be updated/ticked at, if this value is less than or equals to the current + * {@link World#getGameTime()}, then it will be updated in the first possible tick. + * + * @param nextStateUpdateTime The next time that this vault block will be updated/ticked at. + * @see World#getGameTime() + */ + void setNextStateUpdateTime(long nextStateUpdateTime); + + /** + * Gets the players who have used a key on this vault and unlocked it. + * + * @return An unmodifiable collection of player uuids. + * + * @apiNote Only the most recent 128 player UUIDs will be stored by vault blocks. + */ + @Unmodifiable + Collection getRewardedPlayers(); + + /** + * Adds a player as rewarded for this vault. + * + * @param playerUUID The player's uuid. + * @return {@code true} if this player was previously not rewarded, and has been added as a result of this operation. + * + * @apiNote Only the most recent 128 player UUIDs will be stored by vault blocks. Attempting to add more will result in + * the first player UUID being removed. + */ + boolean addRewardedPlayer(UUID playerUUID); + + /** + * Removes a player as rewarded for this vault, allowing them to use a {@link #getKeyItem() key item} again to receive rewards. + * + * @param playerUUID The player's uuid. + * @return {@code true} if this player was previously rewarded, and has been removed as a result of this operation. + * + * @apiNote Only the most recent 128 player UUIDs will be stored by vault blocks. + */ + boolean removeRewardedPlayer(UUID playerUUID); + + /** + * Returns whether a given player has already been rewarded by this vault. + * + * @param playerUUID The player's uuid. + * @return Whether this player was previously rewarded by this vault. + */ + boolean hasRewardedPlayer(UUID playerUUID); + + /** + * Gets an unmodifiable set of "connected players"; players who are inside this vault's activation range and who have not received rewards yet. + * + * @apiNote Vaults will only periodically scan for nearby players, so it may take until the next {@link #getNextStateUpdateTime() update time} for this + * collection to be updated upon a player entering its range. + * + * @return An unmodifiable set of connected player uuids. + */ + @Unmodifiable + Set getConnectedPlayers(); + + /** + * Returns whether a given player is currently connected to this vault. + * + * @param playerUUID the player's uuid + * @return {@code true} if this player is currently connected to this vault. + * + * @see #getConnectedPlayers() + */ + boolean hasConnectedPlayer(UUID playerUUID); + + /** + * Gets the item currently being displayed inside this vault. Displayed items will automatically cycle between random items from the {@link #getDisplayedLootTable()} + * or {@link #getLootTable()} loot tables while this vault is active. + * + * @return The item currently being displayed inside this vault. + */ + ItemStack getDisplayedItem(); + + /** + * Sets the item to display inside this vault until the next cycle. + * + * @param displayedItem The item to display + */ + void setDisplayedItem(ItemStack displayedItem); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultServerData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultServerData.java.patch new file mode 100644 index 000000000..4447be70e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultServerData.java.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/world/level/block/entity/vault/VaultServerData.java ++++ b/net/minecraft/world/level/block/entity/vault/VaultServerData.java +@@ -66,7 +_,12 @@ + + @VisibleForTesting + public void addToRewardedPlayers(Player player) { +- this.rewardedPlayers.add(player.getUUID()); ++ // Paper start - Vault API ++ addToRewardedPlayers(player.getUUID()); ++ } ++ public boolean addToRewardedPlayers(final java.util.UUID player) { ++ final boolean removed = this.rewardedPlayers.add(player); ++ // Paper end - Vault API + if (this.rewardedPlayers.size() > 128) { + Iterator iterator = this.rewardedPlayers.iterator(); + if (iterator.hasNext()) { +@@ -76,6 +_,7 @@ + } + + this.markChanged(); ++ return removed; // Paper - Vault API + } + + public long stateUpdatingResumesAt() { +@@ -131,4 +_,15 @@ + public float ejectionProgress() { + return this.totalEjectionsNeeded == 1 ? 1.0F : 1.0F - Mth.inverseLerp((float)this.getItemsToEject().size(), 1.0F, (float)this.totalEjectionsNeeded); + } ++ ++ // Paper start - Vault API ++ public boolean removeFromRewardedPlayers(final UUID uuid) { ++ if (this.rewardedPlayers.remove(uuid)) { ++ this.markChanged(); ++ return true; ++ } ++ ++ return false; ++ } ++ // Paper end - Vault API + } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftVault.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftVault.java index bfee49828..a8e455ac9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftVault.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftVault.java @@ -1,17 +1,33 @@ package org.bukkit.craftbukkit.block; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.block.entity.vault.VaultBlockEntity; +import net.minecraft.world.level.block.entity.vault.VaultConfig; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Vault; +import org.bukkit.craftbukkit.CraftLootTable; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; +import org.bukkit.loot.LootTable; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +@NullMarked public class CraftVault extends CraftBlockEntityState implements Vault { public CraftVault(World world, VaultBlockEntity tileEntity) { super(world, tileEntity); } - protected CraftVault(CraftVault state, Location location) { + protected CraftVault(CraftVault state, @Nullable Location location) { super(state, location); } @@ -24,4 +40,124 @@ public class CraftVault extends CraftBlockEntityState implemen public CraftVault copy(Location location) { return new CraftVault(this, location); } + + @Override + public double getActivationRange() { + return this.getSnapshot().getConfig().activationRange(); + } + + @Override + public void setActivationRange(final double activationRange) { + Preconditions.checkArgument(Double.isFinite(activationRange), "activation range must not be NaN or infinite"); + Preconditions.checkArgument(activationRange <= this.getDeactivationRange(), "New activation range (%s) must be less or equal to deactivation range (%s)", activationRange, this.getDeactivationRange()); + + final VaultConfig config = this.getSnapshot().getConfig(); + this.getSnapshot().setConfig(new VaultConfig(config.lootTable(), activationRange, config.deactivationRange(), config.keyItem(), config.overrideLootTableToDisplay())); + } + + @Override + public double getDeactivationRange() { + return this.getSnapshot().getConfig().deactivationRange(); + } + + @Override + public void setDeactivationRange(final double deactivationRange) { + Preconditions.checkArgument(Double.isFinite(deactivationRange), "deactivation range must not be NaN or infinite"); + Preconditions.checkArgument(deactivationRange >= this.getActivationRange(), "New deactivation range (%s) must be more or equal to activation range (%s)", deactivationRange, this.getActivationRange()); + + final VaultConfig config = this.getSnapshot().getConfig(); + this.getSnapshot().setConfig(new VaultConfig(config.lootTable(), config.activationRange(), deactivationRange, config.keyItem(), config.overrideLootTableToDisplay())); + } + + @Override + public ItemStack getKeyItem() { + return this.getSnapshot().getConfig().keyItem().asBukkitCopy(); + } + + @Override + public void setKeyItem(final ItemStack key) { + Preconditions.checkArgument(key != null, "key must not be null"); + + final VaultConfig config = this.getSnapshot().getConfig(); + this.getSnapshot().setConfig(new VaultConfig(config.lootTable(), config.activationRange(), config.deactivationRange(), CraftItemStack.asNMSCopy(key), config.overrideLootTableToDisplay())); + } + + @Override + public LootTable getLootTable() { + return CraftLootTable.minecraftToBukkit(this.getSnapshot().getConfig().lootTable()); + } + + @Override + public void setLootTable(final LootTable lootTable) { + final ResourceKey lootTableKey = CraftLootTable.bukkitToMinecraft(lootTable); + Preconditions.checkArgument(lootTableKey != null, "lootTable must not be null"); + + final VaultConfig config = this.getSnapshot().getConfig(); + this.getSnapshot().setConfig(new VaultConfig(lootTableKey, config.activationRange(), config.deactivationRange(), config.keyItem(), config.overrideLootTableToDisplay())); + } + + @Override + public @Nullable LootTable getDisplayedLootTable() { + return this.getSnapshot().getConfig().overrideLootTableToDisplay().map(CraftLootTable::minecraftToBukkit).orElse(null); + } + + @Override + public void setDisplayedLootTable(final @Nullable LootTable lootTable) { + final VaultConfig config = this.getSnapshot().getConfig(); + + this.getSnapshot().setConfig(new VaultConfig(config.lootTable(), config.activationRange(), config.deactivationRange(), config.keyItem(), Optional.ofNullable(CraftLootTable.bukkitToMinecraft(lootTable)))); + } + + @Override + public long getNextStateUpdateTime() { + return this.getSnapshot().serverData.stateUpdatingResumesAt(); + } + + @Override + public void setNextStateUpdateTime(final long nextStateUpdateTime) { + this.getSnapshot().serverData.pauseStateUpdatingUntil(nextStateUpdateTime); + } + + @Override + public @Unmodifiable Collection getRewardedPlayers() { + return ImmutableSet.copyOf(this.getSnapshot().serverData.getRewardedPlayers()); + } + + @Override + public boolean addRewardedPlayer(final UUID playerUUID) { + Preconditions.checkArgument(playerUUID != null, "playerUUID must not be null"); + return this.getSnapshot().serverData.addToRewardedPlayers(playerUUID); + } + + @Override + public boolean removeRewardedPlayer(final UUID playerUUID) { + Preconditions.checkArgument(playerUUID != null, "playerUUID must not be null"); + return this.getSnapshot().serverData.removeFromRewardedPlayers(playerUUID); + } + + @Override + public boolean hasRewardedPlayer(final UUID playerUUID) { + return this.getSnapshot().serverData.getRewardedPlayers().contains(playerUUID); + } + + @Override + public @Unmodifiable Set getConnectedPlayers() { + return ImmutableSet.copyOf(this.getSnapshot().getSharedData().getConnectedPlayers()); + } + + @Override + public boolean hasConnectedPlayer(final UUID playerUUID) { + return this.getSnapshot().getSharedData().getConnectedPlayers().contains(playerUUID); + } + + @Override + public ItemStack getDisplayedItem() { + return CraftItemStack.asBukkitCopy(this.getSnapshot().getSharedData().getDisplayItem()); + } + + @Override + public void setDisplayedItem(final ItemStack displayedItem) { + Preconditions.checkArgument(displayedItem != null, "displayedItem must not be null"); + this.getSnapshot().getSharedData().setDisplayItem(CraftItemStack.asNMSCopy(displayedItem)); + } } From 0a04c3fe228cdb2ab6c4cac2586cb798fe218eff Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Wed, 12 Feb 2025 23:15:37 +0100 Subject: [PATCH 107/203] Fix some NPEs (#12105) --- .../minecraft/world/level/GameRules.java.patch | 8 ++++---- .../org/bukkit/craftbukkit/CraftServer.java | 8 +++++++- .../org/bukkit/craftbukkit/CraftWorld.java | 18 +++++++++--------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch b/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch index 0e251ca8c..e4e113986 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch @@ -129,9 +129,9 @@ - this.value = BoolArgumentType.getBool(context, paramName); + // Paper start - Add WorldGameRuleChangeEvent + protected void updateFromArgument(CommandContext context, String paramName, GameRules.Key gameRuleKey) { -+ io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(context.getSource().getBukkitWorld(), context.getSource().getBukkitSender(), (org.bukkit.GameRule) org.bukkit.GameRule.getByName(gameRuleKey.toString()), String.valueOf(BoolArgumentType.getBool(context, paramName))); -+ if (!event.callEvent()) return; -+ this.value = Boolean.parseBoolean(event.getValue()); ++ io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(context.getSource().getBukkitWorld(), context.getSource().getBukkitSender(), (org.bukkit.GameRule) org.bukkit.GameRule.getByName(gameRuleKey.toString()), String.valueOf(BoolArgumentType.getBool(context, paramName))); ++ if (!event.callEvent()) return; ++ this.value = Boolean.parseBoolean(event.getValue()); + // Paper end - Add WorldGameRuleChangeEvent } @@ -197,7 +197,7 @@ + io.papermc.paper.event.world.WorldGameRuleChangeEvent event = new io.papermc.paper.event.world.WorldGameRuleChangeEvent(context.getSource().getBukkitWorld(), context.getSource().getBukkitSender(), (org.bukkit.GameRule) org.bukkit.GameRule.getByName(gameRuleKey.toString()), String.valueOf(IntegerArgumentType.getInteger(context, paramName))); + if (!event.callEvent()) return; + this.value = Integer.parseInt(event.getValue()); -+ // Paper end - Add WorldGameRuleChangeEvent ++ // Paper end - Add WorldGameRuleChangeEvent } public int get() { 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 d162c9c57..cf5bcb0eb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -131,6 +131,7 @@ import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.WorldBorder; import org.bukkit.WorldCreator; +import org.bukkit.block.BlockType; import org.bukkit.block.data.BlockData; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarFlag; @@ -2852,8 +2853,13 @@ public final class CraftServer implements Server { @Override public BlockData createBlockData(org.bukkit.Material material, String data) { Preconditions.checkArgument(material != null || data != null, "Must provide one of material or data"); + BlockType type = null; + if (material != null) { + type = material.asBlockType(); + Preconditions.checkArgument(type != null, "Provided material must be a block"); + } - return CraftBlockData.newData((material != null) ? material.asBlockType() : null, data); + return CraftBlockData.newData(type, data); } @Override 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 284b58ece..600a0f423 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -2,14 +2,11 @@ package org.bukkit.craftbukkit; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.mojang.datafixers.util.Pair; import io.papermc.paper.FeatureHooks; import io.papermc.paper.raytracing.RayTraceTarget; import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilder; import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilderImpl; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; @@ -45,13 +42,11 @@ import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.DistanceManager; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.Ticket; import net.minecraft.server.level.TicketType; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.Mth; -import net.minecraft.util.SortedArraySet; import net.minecraft.util.Unit; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; @@ -87,7 +82,6 @@ import org.bukkit.NamespacedKey; import org.bukkit.Note; import org.bukkit.Particle; import org.bukkit.Raid; -import org.bukkit.Registry; import org.bukkit.Sound; import org.bukkit.TreeType; import org.bukkit.World; @@ -2078,13 +2072,19 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public T getGameRuleValue(GameRule rule) { Preconditions.checkArgument(rule != null, "GameRule cannot be null"); - return this.convert(rule, this.getHandle().getGameRules().getRule(this.getGameRulesNMS().get(rule.getName()))); + GameRules.Key> key = this.getGameRulesNMS().get(rule.getName()); + Preconditions.checkArgument(key != null, "GameRule '%s' is not available", rule.getName()); + + return this.getGameRuleResult(rule, this.getHandle().getGameRules().getRule(key)); } @Override public T getGameRuleDefault(GameRule rule) { Preconditions.checkArgument(rule != null, "GameRule cannot be null"); - return this.convert(rule, this.getGameRuleDefinitions().get(rule.getName()).createRule()); + GameRules.Type type = this.getGameRuleDefinitions().get(rule.getName()); + Preconditions.checkArgument(type != null, "GameRule '%s' is not available", rule.getName()); + + return this.getGameRuleResult(rule, type.createRule()); } @Override @@ -2104,7 +2104,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { return true; } - private T convert(GameRule rule, GameRules.Value value) { + private T getGameRuleResult(GameRule rule, GameRules.Value value) { if (value == null) { return null; } From 06804850959261b5b97ee120d17593621f7090bd Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Wed, 12 Feb 2025 19:24:46 -0300 Subject: [PATCH 108/203] Expand TrialSpawner API (#12025) --- build-data/paper.at | 2 + .../java/org/bukkit/block/TrialSpawner.java | 69 +++++++++++++------ .../craftbukkit/block/CraftTrialSpawner.java | 20 ++++++ 3 files changed, 70 insertions(+), 21 deletions(-) diff --git a/build-data/paper.at b/build-data/paper.at index 8e27f7157..d1158d474 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -625,8 +625,10 @@ public net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity exitPorta public net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity trialSpawner public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner isOminous public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner stateAccessor +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData cooldownEndsAt public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData currentMobs public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData detectedPlayers +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextMobSpawnsAt public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextSpawnData public net.minecraft.world.level.block.entity.vault.VaultBlockEntity serverData public net.minecraft.world.level.block.entity.vault.VaultServerData getRewardedPlayers()Ljava/util/Set; diff --git a/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java b/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java index 6c1e3b5f3..03263a270 100644 --- a/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java +++ b/paper-api/src/main/java/org/bukkit/block/TrialSpawner.java @@ -4,26 +4,57 @@ import java.util.Collection; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.spawner.TrialSpawnerConfiguration; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked; /** * Represents a captured state of a trial spawner. */ +@NullMarked public interface TrialSpawner extends TileState { + /** + * Gets the game time in ticks when the cooldown ends. 0 if not currently in cooldown. + * + * @return the game time in ticks + * @see org.bukkit.World#getGameTime() + */ + long getCooldownEnd(); + + /** + * Sets the game time in ticks when the cooldown ends. + * + * @param ticks the game time in ticks for the new cooldown + */ + void setCooldownEnd(long ticks); + + /** + * Gets the game time in ticks when the next spawn attempt happens. 0 if not currently active. + * + * @return the game time in ticks + * @see org.bukkit.World#getGameTime() + */ + long getNextSpawnAttempt(); + + /** + * Sets the game time in ticks when the next spawn attempt happens. + * + * @param ticks the game time in ticks for the next mob spawn + */ + void setNextSpawnAttempt(long ticks); + /** * Gets the length in ticks the spawner will stay in cooldown for. * * @return the number of ticks */ - public int getCooldownLength(); + int getCooldownLength(); /** * Sets the length in ticks the spawner will stay in cooldown for. * * @param ticks the number of ticks */ - public void setCooldownLength(int ticks); + void setCooldownLength(int ticks); /** * Get the maximum distance(squared) a player can be in order for this @@ -37,7 +68,7 @@ public interface TrialSpawner extends TileState { * @return the maximum distance(squared) a player can be in order for this * spawner to be active. */ - public int getRequiredPlayerRange(); + int getRequiredPlayerRange(); /** * Set the maximum distance (squared) a player can be in order for this @@ -49,7 +80,7 @@ public interface TrialSpawner extends TileState { * @param requiredPlayerRange the maximum distance (squared) a player can be * in order for this spawner to be active. */ - public void setRequiredPlayerRange(int requiredPlayerRange); + void setRequiredPlayerRange(int requiredPlayerRange); /** * Gets the players this spawner is currently tracking. @@ -61,8 +92,7 @@ public interface TrialSpawner extends TileState { * @return a collection of players this spawner is tracking or an empty * collection if there aren't any */ - @NotNull - public Collection getTrackedPlayers(); + Collection getTrackedPlayers(); /** * Checks if this spawner is currently tracking the provided player. @@ -70,7 +100,7 @@ public interface TrialSpawner extends TileState { * @param player the player * @return true if this spawner is tracking the provided player */ - public boolean isTrackingPlayer(@NotNull Player player); + boolean isTrackingPlayer(final Player player); /** * Force this spawner to start tracking the provided player. @@ -80,7 +110,7 @@ public interface TrialSpawner extends TileState { * * @param player the player */ - public void startTrackingPlayer(@NotNull Player player); + void startTrackingPlayer(final Player player); /** * Force this spawner to stop tracking the provided player. @@ -90,7 +120,7 @@ public interface TrialSpawner extends TileState { * * @param player the player */ - public void stopTrackingPlayer(@NotNull Player player); + void stopTrackingPlayer(final Player player); /** * Gets a list of entities this spawner is currently tracking. @@ -102,8 +132,7 @@ public interface TrialSpawner extends TileState { * @return a collection of entities this spawner is tracking or an empty * collection if there aren't any */ - @NotNull - public Collection getTrackedEntities(); + Collection getTrackedEntities(); /** * Checks if this spawner is currently tracking the provided entity. @@ -111,7 +140,7 @@ public interface TrialSpawner extends TileState { * @param entity the entity * @return true if this spawner is tracking the provided entity */ - public boolean isTrackingEntity(@NotNull Entity entity); + boolean isTrackingEntity(final Entity entity); /** * Force this spawner to start tracking the provided entity. @@ -121,7 +150,7 @@ public interface TrialSpawner extends TileState { * * @param entity the entity */ - public void startTrackingEntity(@NotNull Entity entity); + void startTrackingEntity(final Entity entity); /** * Force this spawner to stop tracking the provided entity. @@ -131,7 +160,7 @@ public interface TrialSpawner extends TileState { * * @param entity the entity */ - public void stopTrackingEntity(@NotNull Entity entity); + void stopTrackingEntity(final Entity entity); /** * Checks if this spawner is using the ominous @@ -139,7 +168,7 @@ public interface TrialSpawner extends TileState { * * @return true is using the ominous configuration */ - public boolean isOminous(); + boolean isOminous(); /** * Changes this spawner between the normal and ominous @@ -148,7 +177,7 @@ public interface TrialSpawner extends TileState { * @param ominous true to use the ominous TrialSpawnerConfiguration, false to * use the normal one. */ - public void setOminous(boolean ominous); + void setOminous(boolean ominous); /** * Gets the {@link TrialSpawnerConfiguration} used when {@link #isOminous()} is @@ -156,8 +185,7 @@ public interface TrialSpawner extends TileState { * * @return the TrialSpawnerConfiguration */ - @NotNull - public TrialSpawnerConfiguration getNormalConfiguration(); + TrialSpawnerConfiguration getNormalConfiguration(); /** * Gets the {@link TrialSpawnerConfiguration} used when {@link #isOminous()} is @@ -165,6 +193,5 @@ public interface TrialSpawner extends TileState { * * @return the TrialSpawnerConfiguration */ - @NotNull - public TrialSpawnerConfiguration getOminousConfiguration(); + TrialSpawnerConfiguration getOminousConfiguration(); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java index a8f266438..c3b395a1f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java @@ -33,6 +33,26 @@ public class CraftTrialSpawner extends CraftBlockEntityState Date: Wed, 12 Feb 2025 23:30:41 +0100 Subject: [PATCH 109/203] Add support for rotation argument handling (#12090) --- .../brigadier/argument/ArgumentTypes.java | 10 +++++ .../argument/VanillaArgumentProvider.java | 3 ++ .../argument/resolvers/RotationResolver.java | 16 ++++++++ .../java/io/papermc/paper/math/Rotation.java | 34 +++++++++++++++ .../io/papermc/paper/math/RotationImpl.java | 4 ++ .../src/main/java/org/bukkit/Location.java | 41 +++++++++++++++++++ .../argument/VanillaArgumentProviderImpl.java | 13 ++++++ 7 files changed, 121 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/RotationResolver.java create mode 100644 paper-api/src/main/java/io/papermc/paper/math/Rotation.java create mode 100644 paper-api/src/main/java/io/papermc/paper/math/RotationImpl.java diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java index 9abb9ff33..440cfcfa5 100644 --- a/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java @@ -7,6 +7,7 @@ import io.papermc.paper.command.brigadier.argument.range.IntegerRangeProvider; import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver; +import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.EntitySelectorArgumentResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; import io.papermc.paper.entity.LookAnchor; @@ -123,6 +124,15 @@ public final class ArgumentTypes { return provider().finePosition(centerIntegers); } + /** + * A rotation argument. + * + * @return rotation argument + */ + public static ArgumentType rotation() { + return provider().rotation(); + } + /** * A blockstate argument which will provide rich parsing for specifying * the specific block variant and then the block entity NBT if applicable. diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java index 4f640bd3e..7f30fc567 100644 --- a/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/VanillaArgumentProvider.java @@ -7,6 +7,7 @@ import io.papermc.paper.command.brigadier.argument.range.IntegerRangeProvider; import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver; +import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.EntitySelectorArgumentResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; import io.papermc.paper.entity.LookAnchor; @@ -57,6 +58,8 @@ interface VanillaArgumentProvider { ArgumentType finePosition(boolean centerIntegers); + ArgumentType rotation(); + ArgumentType blockState(); ArgumentType itemStack(); diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/RotationResolver.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/RotationResolver.java new file mode 100644 index 000000000..fe697d183 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/RotationResolver.java @@ -0,0 +1,16 @@ +package io.papermc.paper.command.brigadier.argument.resolvers; + +import io.papermc.paper.command.brigadier.CommandSourceStack; +import io.papermc.paper.math.Rotation; +import org.jetbrains.annotations.ApiStatus; + +/** + * An {@link ArgumentResolver} that's capable of resolving + * a rotation argument value using a {@link CommandSourceStack}. + * + * @see io.papermc.paper.command.brigadier.argument.ArgumentTypes#rotation() + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface RotationResolver extends ArgumentResolver { +} diff --git a/paper-api/src/main/java/io/papermc/paper/math/Rotation.java b/paper-api/src/main/java/io/papermc/paper/math/Rotation.java new file mode 100644 index 000000000..73add399e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/math/Rotation.java @@ -0,0 +1,34 @@ +package io.papermc.paper.math; + +import org.jspecify.annotations.NullMarked; + +/** + * Represents a rotation with specified pitch and yaw values. + */ +@NullMarked +public interface Rotation { + /** + * Creates a new rotation with the specified yaw and pitch values. + * + * @param yaw the yaw component of the rotation, measured in degrees + * @param pitch the pitch component of the rotation, measured in degrees + * @return a new {@code Rotation} instance with the specified yaw and pitch + */ + static Rotation rotation(float yaw, float pitch) { + return new RotationImpl(yaw, pitch); + } + + /** + * Retrieves the pitch component of the rotation, measured in degrees. + * + * @return the pitch value in degrees + */ + float pitch(); + + /** + * Retrieves the yaw component of the rotation, measured in degrees. + * + * @return the yaw value in degrees + */ + float yaw(); +} diff --git a/paper-api/src/main/java/io/papermc/paper/math/RotationImpl.java b/paper-api/src/main/java/io/papermc/paper/math/RotationImpl.java new file mode 100644 index 000000000..a5cff7deb --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/math/RotationImpl.java @@ -0,0 +1,4 @@ +package io.papermc.paper.math; + +record RotationImpl(float yaw, float pitch) implements Rotation { +} diff --git a/paper-api/src/main/java/org/bukkit/Location.java b/paper-api/src/main/java/org/bukkit/Location.java index 8bc340c9d..20e30fa5a 100644 --- a/paper-api/src/main/java/org/bukkit/Location.java +++ b/paper-api/src/main/java/org/bukkit/Location.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Predicate; import io.papermc.paper.math.FinePosition; +import io.papermc.paper.math.Rotation; import org.bukkit.block.Block; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.Entity; @@ -411,6 +412,19 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } + /** + * Adds rotation to this location. Not world-aware. + * + * @param rotation the rotation to add. + * @return the same location + * @see Vector + */ + @NotNull + @Contract(value = "_ -> this", mutates = "this") + public Location addRotation(@NotNull Rotation rotation) { + return addRotation(rotation.yaw(), rotation.pitch()); + } + /** * Subtracts the location by another. * @@ -480,6 +494,19 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } + /** + * Subtracts rotation from this location. + * + * @param rotation the rotation to subtract. + * @return the same location + * @see Vector + */ + @NotNull + @Contract(value = "_ -> this", mutates = "this") + public Location subtractRotation(@NotNull Rotation rotation) { + return subtractRotation(rotation.yaw(), rotation.pitch()); + } + /** * Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The * value of this method is not cached and uses a costly square-root @@ -622,6 +649,20 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm return this; } + /** + * Sets the rotation of this location and returns itself. + *

+ * This mutates this object, clone first. + * + * @param rotation the new rotation. + * @return self (not cloned) + */ + @NotNull + @Contract(value = "_ -> this", mutates = "this") + public Location setRotation(@NotNull Rotation rotation) { + return setRotation(rotation.yaw(), rotation.pitch()); + } + /** * Takes the x/y/z from base and adds the specified x/y/z to it and returns self *

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 38fb7d13a..3cfe31942 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 @@ -19,9 +19,11 @@ import io.papermc.paper.command.brigadier.argument.range.RangeProvider; import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver; +import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.EntitySelectorArgumentResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; import io.papermc.paper.entity.LookAnchor; +import io.papermc.paper.math.Rotation; import io.papermc.paper.registry.PaperRegistries; import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; @@ -61,6 +63,7 @@ import net.minecraft.commands.arguments.TimeArgument; import net.minecraft.commands.arguments.UuidArgument; import net.minecraft.commands.arguments.blocks.BlockStateArgument; import net.minecraft.commands.arguments.coordinates.BlockPosArgument; +import net.minecraft.commands.arguments.coordinates.RotationArgument; import net.minecraft.commands.arguments.coordinates.Vec3Argument; import net.minecraft.commands.arguments.item.ItemArgument; import net.minecraft.commands.arguments.item.ItemPredicateArgument; @@ -71,6 +74,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.bukkit.GameMode; import org.bukkit.HeightMap; @@ -156,6 +160,15 @@ public class VanillaArgumentProviderImpl implements VanillaArgumentProvider { }); } + @Override + public ArgumentType rotation() { + return this.wrap(RotationArgument.rotation(), (result) -> sourceStack -> { + final Vec2 vec2 = result.getRotation((CommandSourceStack) sourceStack); + + return Rotation.rotation(vec2.y, vec2.x); + }); + } + @Override public ArgumentType blockState() { return this.wrap(BlockStateArgument.block(PaperCommands.INSTANCE.getBuildContext()), (result) -> { From 6cfa2f7f315cbad23d7b12984b751f2721b496b6 Mon Sep 17 00:00:00 2001 From: David <54660361+NonSwag@users.noreply.github.com> Date: Fri, 14 Feb 2025 18:39:44 +0100 Subject: [PATCH 110/203] [ci skip] Add missing nullability annotation to sendEquipmentChange method (#12112) Marked ItemStack parameter as `@Nullable` to explicitly indicate it can be null. This improves clarity, avoids nullability problems, and aligns with the method's documented behavior for handling null values. --- paper-api/src/main/java/org/bukkit/entity/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0081dd53b..69f982d1d 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Player.java +++ b/paper-api/src/main/java/org/bukkit/entity/Player.java @@ -1061,7 +1061,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @param items the slots to change, where the values are the items to which * the slot should be changed. null values will set the slot to air, empty map is not allowed */ - public void sendEquipmentChange(LivingEntity entity, Map items); + public void sendEquipmentChange(LivingEntity entity, Map items); // Paper start /** From 9b9de827065e63eb6262bd6c6ef905246df2811a Mon Sep 17 00:00:00 2001 From: Space Walker <48224626+SpaceWalkerRS@users.noreply.github.com> Date: Sat, 15 Feb 2025 12:40:31 +0100 Subject: [PATCH 111/203] Update Alternate Current patch to v1.9.1 (#12115) --- ...19-Add-Alternate-Current-redstone-implementation.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch b/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch index 98d1bff65..64f9aa7ab 100644 --- a/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch +++ b/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch @@ -22,7 +22,7 @@ Alternate Current's wire handler. diff --git a/alternate/current/wire/LevelHelper.java b/alternate/current/wire/LevelHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..eda108e2df9bf7d1ddd89287b8d2c2d7f1637c96 +index 0000000000000000000000000000000000000000..ff663d3089627e75221aa128aff4bf5cc459addb --- /dev/null +++ b/alternate/current/wire/LevelHelper.java @@ -0,0 +1,66 @@ @@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..eda108e2df9bf7d1ddd89287b8d2c2d7 + static boolean setWireState(ServerLevel level, BlockPos pos, BlockState state, boolean updateNeighborShapes) { + int y = pos.getY(); + -+ if (y < level.getMinY() || y >= level.getMaxY()) { ++ if (y < level.getMinY() || y > level.getMaxY()) { + return false; + } + @@ -2326,7 +2326,7 @@ index 0000000000000000000000000000000000000000..298076a0db4e6ee6e4775ac43bf749d9 + } +} diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 95a4e37a3c93f9b3c56c7a7376ed521cd46fbb6f..46dfaed12c998c219a20c711a06531aed2c68012 100644 +index a293d1481b5f4a1d18addc3e518486c639223f09..5bf38ab129451e867b638cfbd2d7be59cbf7f38d 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -214,6 +214,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -2352,7 +2352,7 @@ index 95a4e37a3c93f9b3c56c7a7376ed521cd46fbb6f..46dfaed12c998c219a20c711a06531ae @Override public void onCreated(Entity entity) { diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 8331b49185500ab3b4307e9ae05126b4f83a318a..2bbebb4335d927f240abcac67a5b423e38dc33d7 100644 +index a768f041fd16d253ec4ab5eb75288b1771d5cb00..1dbe7c7c1051c3972105534a07ce50d4cf98fc85 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -2099,6 +2099,17 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl From c62252e19fc6a5f135b69ee94cd4fa8ea81f4b01 Mon Sep 17 00:00:00 2001 From: Epic Date: Sat, 15 Feb 2025 22:30:32 +0000 Subject: [PATCH 112/203] Add lore content guard (#12116) * add content guard * use preconditions for null check --- .../craftbukkit/inventory/CraftMetaItem.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index eb7d90cfa..5bff7a4d6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -1250,8 +1250,18 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { @Override public void lore(final List lore) { - Preconditions.checkArgument(lore == null || lore.size() <= ItemLore.MAX_LINES, "lore cannot have more than %s lines", ItemLore.MAX_LINES); // Paper - limit lore lines - this.lore = lore != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(lore) : null; + if (lore == null) { + this.lore = null; + return; + } + + Preconditions.checkArgument(lore.size() <= ItemLore.MAX_LINES, "lore cannot have more than %s lines", ItemLore.MAX_LINES); // Paper - limit lore lines + + for (int i = 0; i < lore.size(); i++) { + Preconditions.checkArgument(lore.get(i) != null, "lore contains null entry at index: %s", i); + } + + this.lore = io.papermc.paper.adventure.PaperAdventure.asVanilla(lore); } // Paper end From 404167841dcf3ac78792ffbd45c683a2173b4b08 Mon Sep 17 00:00:00 2001 From: masmc05 <63639746+masmc05@users.noreply.github.com> Date: Sun, 16 Feb 2025 00:31:42 +0200 Subject: [PATCH 113/203] [ci-skip] Mention missing World#regenerateChunk implementation in jd (#12109) * Mention missing impl * Clean the implementation out of years old code * Change the jd comment * Move to default method --------- Co-authored-by: Bjarne Koll --- paper-api/src/main/java/org/bukkit/World.java | 7 +++-- .../org/bukkit/craftbukkit/CraftWorld.java | 27 ------------------- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index 2729f71ac..27c4fcba6 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -476,12 +476,15 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @param z Z-coordinate of the chunk * @return Whether the chunk was actually regenerated * + * @throws UnsupportedOperationException not implemented * @deprecated regenerating a single chunk is not likely to produce the same * chunk as before as terrain decoration may be spread across chunks. It may * or may not change blocks in the adjacent chunks as well. */ - @Deprecated(since = "1.13") - public boolean regenerateChunk(int x, int z); + @Deprecated(since = "1.13", forRemoval = true) + default boolean regenerateChunk(int x, int z) { + throw new UnsupportedOperationException("Not supported in this Minecraft version! This is not a bug."); + } /** * Resends the {@link Chunk} to all clients 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 600a0f423..1439d2821 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -470,33 +470,6 @@ public class CraftWorld extends CraftRegionAccessor implements World { return !this.isChunkLoaded(x, z); } - @Override - public boolean regenerateChunk(int x, int z) { - org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot - throw new UnsupportedOperationException("Not supported in this Minecraft version! Unless you can fix it, this is not a bug :)"); - /* - if (!unloadChunk0(x, z, false)) { - return false; - } - warnUnsafeChunk("regenerating a faraway chunk", x, z); // Paper - - final long chunkKey = ChunkCoordIntPair.pair(x, z); - world.getChunkProvider().unloadQueue.remove(chunkKey); - - net.minecraft.server.Chunk chunk = world.getChunkProvider().generateChunk(x, z); - PlayerChunk playerChunk = world.getPlayerChunkMap().getChunk(x, z); - if (playerChunk != null) { - playerChunk.chunk = chunk; - } - - if (chunk != null) { - refreshChunk(x, z); - } - - return chunk != null; - */ - } - @Override public boolean refreshChunk(int x, int z) { ChunkHolder playerChunk = this.world.getChunkSource().chunkMap.getVisibleChunkIfPresent(ChunkPos.asLong(x, z)); From a6e82d90ce54d3e9cfd26e81c1ef4c8ffc4bc32e Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 16 Feb 2025 19:13:35 +0100 Subject: [PATCH 114/203] [ci skip] Clarify getChunkAtAsyncUrgently javadocs (#12125) --- paper-api/src/main/java/org/bukkit/World.java | 76 ++++++++++++------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index 27c4fcba6..987a98074 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -1481,14 +1481,14 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Requests a {@link Chunk} to be loaded at the given coordinates - * + *

* This method makes no guarantee on how fast the chunk will load, * and will return the chunk to the callback at a later time. - * + *

* You should use this method if you need a chunk but do not need it - * immediately, and you wish to let the server control the speed - * of chunk loads, keeping performance in mind. - * + * immediately, and you wish for it to be prioritised over other + * chunk loads in queue. + *

* The future will always be executed synchronously * on the main Server Thread. * @param loc Location to load the corresponding chunk from @@ -1500,14 +1500,14 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Requests a {@link Chunk} to be loaded at the given coordinates - * + *

* This method makes no guarantee on how fast the chunk will load, * and will return the chunk to the callback at a later time. - * + *

* You should use this method if you need a chunk but do not need it - * immediately, and you wish to let the server control the speed - * of chunk loads, keeping performance in mind. - * + * immediately, and you wish for it to be prioritised over other + * chunk loads in queue. + *

* The future will always be executed synchronously * on the main Server Thread. * @param loc Location to load the corresponding chunk from @@ -1520,14 +1520,14 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Requests a {@link Chunk} to be loaded at the given coordinates - * + *

* This method makes no guarantee on how fast the chunk will load, * and will return the chunk to the callback at a later time. - * + *

* You should use this method if you need a chunk but do not need it - * immediately, and you wish to let the server control the speed - * of chunk loads, keeping performance in mind. - * + * immediately, and you wish for it to be prioritised over other + * chunk loads in queue. + *

* The future will always be executed synchronously * on the main Server Thread. * @param block Block to load the corresponding chunk from @@ -1539,14 +1539,14 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Requests a {@link Chunk} to be loaded at the given coordinates - * + *

* This method makes no guarantee on how fast the chunk will load, * and will return the chunk to the callback at a later time. - * + *

* You should use this method if you need a chunk but do not need it - * immediately, and you wish to let the server control the speed - * of chunk loads, keeping performance in mind. - * + * immediately, and you wish for it to be prioritised over other + * chunk loads in queue. + *

* The future will always be executed synchronously * on the main Server Thread. * @param block Block to load the corresponding chunk from @@ -1559,25 +1559,45 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Requests a {@link Chunk} to be loaded at the given coordinates - * + *

* This method makes no guarantee on how fast the chunk will load, - * and will return the chunk to the callback at a later time. - * + * and will complete the future at a later time. + *

* You should use this method if you need a chunk but do not need it - * immediately, and you wish to let the server control the speed - * of chunk loads, keeping performance in mind. - * + * immediately, and you wish for it to be prioritised over other + * chunk loads in queue. + *

* The future will always be executed synchronously * on the main Server Thread. * - * @param x X Coord - * @param z Z Coord + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @return Future that will resolve when the chunk is loaded */ default @NotNull java.util.concurrent.CompletableFuture getChunkAtAsyncUrgently(final int x, final int z) { return this.getChunkAtAsync(x, z, true, true); } + /** + * Requests a {@link Chunk} to be loaded at the given coordinates. + *

+ * This method makes no guarantee on how fast the chunk will load, + * and will return the chunk to the callback at a later time. + *

+ * You should use this method if you need a chunk but do not need it + * immediately, and you wish to let the server control the speed + * of chunk loads, keeping performance in mind. + *

+ * The future will always be executed synchronously + * on the main Server Thread. + * + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate + * @param gen Should the chunk generate if it doesn't exist + * @param urgent If true, the chunk may be prioritised to be loaded above other chunks in queue + * + * @return Future that will resolve when the chunk is loaded + */ default @NotNull java.util.concurrent.CompletableFuture getChunkAtAsync(int x, int z, boolean gen, boolean urgent) { java.util.concurrent.CompletableFuture ret = new java.util.concurrent.CompletableFuture<>(); this.getChunkAtAsync(x, z, gen, urgent, ret::complete); From cb25c0cf3134d22163c090d93126ef4fb23193b8 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sun, 16 Feb 2025 15:17:26 -0300 Subject: [PATCH 115/203] [ci skip] Fix annotation fields used in NMS getBukkitEntity (#12120) --- .../features/0006-Optimize-Collision-to-not-load-chunks.patch | 2 +- .../minecraft/server/bossevents/CustomBossEvent.java.patch | 2 +- .../sources/net/minecraft/world/entity/Entity.java.patch | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch index ca6297da9..d511d3079 100644 --- a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch +++ b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch @@ -22,7 +22,7 @@ index 334859c5ff7023c730513301cc11c9837b2c7823..45f69a914d5a0565196c4105d6154104 public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + public boolean collisionLoadChunks = false; // Paper - private org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; + private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() { diff --git a/net/minecraft/world/level/BlockCollisions.java b/net/minecraft/world/level/BlockCollisions.java diff --git a/paper-server/patches/sources/net/minecraft/server/bossevents/CustomBossEvent.java.patch b/paper-server/patches/sources/net/minecraft/server/bossevents/CustomBossEvent.java.patch index 9aa2e7d86..3338d7d8b 100644 --- a/paper-server/patches/sources/net/minecraft/server/bossevents/CustomBossEvent.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/bossevents/CustomBossEvent.java.patch @@ -5,7 +5,7 @@ private int value; private int max = 100; + // CraftBukkit start -+ private org.bukkit.boss.KeyedBossBar bossBar; ++ private @javax.annotation.Nullable org.bukkit.boss.KeyedBossBar bossBar; + + public org.bukkit.boss.KeyedBossBar getBukkitEntity() { + if (this.bossBar == null) { 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 d4f61b665..691432fd2 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 @@ -86,7 +86,7 @@ + // Paper end - Share random for entities to make them more random + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + -+ private org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; ++ private @Nullable org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity; + + public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntity() { + if (this.bukkitEntity == null) { @@ -101,7 +101,7 @@ + return this.bukkitEntity; + } + // Paper start -+ public org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntityRaw() { ++ public @Nullable org.bukkit.craftbukkit.entity.CraftEntity getBukkitEntityRaw() { + return this.bukkitEntity; + } + // Paper end From 00701267c86ee89606c9a290ce3ff60bfc724712 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sun, 16 Feb 2025 15:19:42 -0300 Subject: [PATCH 116/203] [ci skip] improvement example in javadoc for DatapackRegistrar (#12122) --- .../java/io/papermc/paper/datapack/DatapackRegistrar.java | 7 +++++-- .../java/io/papermc/paper/tag/PostFlattenTagRegistrar.java | 4 ++-- .../java/io/papermc/paper/tag/PreFlattenTagRegistrar.java | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java b/paper-api/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java index b009df66d..e2f533a82 100644 --- a/paper-api/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java +++ b/paper-api/src/main/java/io/papermc/paper/datapack/DatapackRegistrar.java @@ -19,11 +19,13 @@ import org.jspecify.annotations.Nullable; * is called anytime the game tries to discover datapacks at any of the * configured locations. This means that if a datapack should stay available to the server, * it must always be discovered whenever this event fires. - *

An example of a plugin loading a datapack from within it's own jar is below

+ *

+ * An example of a plugin loading a datapack from within its own jar is below, + * assuming the datapack is included under {@code resources/pack} folder: *

{@code
  * public class YourPluginBootstrap implements PluginBootstrap {
  *     @Override
- *     public void bootstrap(BoostrapContext context) {
+ *     public void bootstrap(BootstrapContext context) {
  *         final LifecycleEventManager manager = context.getLifecycleManager();
  *         manager.registerEventHandler(LifecycleEvents.DATAPACK_DISCOVERY, event -> {
  *             DatapackRegistrar registrar = event.registrar();
@@ -39,6 +41,7 @@ import org.jspecify.annotations.Nullable;
  *     }
  * }
  * }
+ * * @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#DATAPACK_DISCOVERY */ @ApiStatus.NonExtendable diff --git a/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java b/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java index 909abcb18..a8d53a1b6 100644 --- a/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java +++ b/paper-api/src/main/java/io/papermc/paper/tag/PostFlattenTagRegistrar.java @@ -19,7 +19,7 @@ import org.jspecify.annotations.NullMarked; * tags only point to individual entries and not other nested tags. *

* An example of a custom enchant being registered to the vanilla - * {@code #minecraft:in_enchanting_table} tag. + * {@code #minecraft:in_enchanting_table} tag: *

{@code
  * class YourBootstrapClass implements PluginBootstrap {
  *
@@ -27,7 +27,7 @@ import org.jspecify.annotations.NullMarked;
  *
  *     @Override
  *     public void bootstrap(BootstrapContext context) {
- *         LifecycleEventManager manager = context.getLifecycleManager();
+ *         final LifecycleEventManager manager = context.getLifecycleManager();
  *         manager.registerEventHandler(LifecycleEvents.TAGS.postFlatten(RegistryKey.ENCHANTMENT), event -> {
  *             final PostFlattenTagRegistrar registrar = event.registrar();
  *             registrar.addToTag(
diff --git a/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java b/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java
index 7c00ad45f..5c42ab605 100644
--- a/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java
+++ b/paper-api/src/main/java/io/papermc/paper/tag/PreFlattenTagRegistrar.java
@@ -22,11 +22,11 @@ import org.jspecify.annotations.NullMarked;
  * 
{@code
  * class YourBootstrapClass implements PluginBootstrap {
  *
- *     public static final TagKey AXE_PICKAXE = TagKey.create(RegistryKey.ITEM, Key.key("papermc:axe_pickaxe"));
+ *     public static final TagKey AXE_PICKAXE = ItemTypeTagKeys.create(Key.key("papermc:axe_pickaxe"));
  *
  *     @Override
  *     public void bootstrap(BootstrapContext context) {
- *         LifecycleEventManager manager = context.getLifecycleManager();
+ *         final LifecycleEventManager manager = context.getLifecycleManager();
  *         manager.registerEventHandler(LifecycleEvents.TAGS.preFlatten(RegistryKey.ITEM), event -> {
  *             final PreFlattenTagRegistrar registrar = event.registrar();
  *             registrar.setTag(AXE_PICKAXE, Set.of(

From 608f004a2cb315f1e1003e7cdb9244693a097e80 Mon Sep 17 00:00:00 2001
From: Jake Potrebic 
Date: Sun, 16 Feb 2025 11:01:37 -0800
Subject: [PATCH 117/203] add method on ItemStack to edit pdc (#12022)

---
 .../java/org/bukkit/inventory/ItemStack.java  | 20 +++++++++-
 .../craftbukkit/inventory/CraftItemStack.java | 37 ++++++++++++++++---
 .../craftbukkit/inventory/CraftMetaItem.java  |  2 +-
 3 files changed, 51 insertions(+), 8 deletions(-)

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 55457c753..c84cddac8 100644
--- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java
+++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -1,16 +1,15 @@
 package org.bukkit.inventory;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
 import io.papermc.paper.registry.RegistryKey;
 import java.util.LinkedHashMap;
 import java.util.Locale;
 import java.util.Map;
+import java.util.function.Consumer;
 import net.kyori.adventure.text.Component;
 import org.bukkit.Bukkit;
 import org.bukkit.Material;
 import org.bukkit.NamespacedKey;
-import org.bukkit.Registry;
 import org.bukkit.Translatable;
 import org.bukkit.UndefinedNullability;
 import org.bukkit.Utility;
@@ -19,6 +18,7 @@ import org.bukkit.enchantments.Enchantment;
 import org.bukkit.inventory.meta.Damageable;
 import org.bukkit.inventory.meta.ItemMeta;
 import org.bukkit.material.MaterialData;
+import org.bukkit.persistence.PersistentDataContainer;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -64,10 +64,26 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
     // Paper end
 
     // Paper start - pdc
+    /**
+     * @see #editPersistentDataContainer(Consumer)
+     */
     @Override
     public io.papermc.paper.persistence.@NotNull PersistentDataContainerView getPersistentDataContainer() {
         return this.craftDelegate.getPersistentDataContainer();
     }
+
+    /**
+     * Edits the {@link PersistentDataContainer} of this stack. The
+     * {@link PersistentDataContainer} instance is only valid inside the
+     * consumer.
+     *
+     * @param consumer the persistent data container consumer
+     * @return {@code true} if the edit was successful, {@code false} otherwise. Failure to edit the persistent data
+     * container may be caused by empty or invalid itemstacks.
+     */
+    public boolean editPersistentDataContainer(@NotNull Consumer consumer) {
+        return this.craftDelegate.editPersistentDataContainer(consumer);
+    }
     // Paper end - pdc
 
     @Utility
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 379997369..a6668ae29 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
@@ -2,10 +2,11 @@ package org.bukkit.craftbukkit.inventory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
+import io.papermc.paper.adventure.PaperAdventure;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Optional;
-import io.papermc.paper.adventure.PaperAdventure;
+import java.util.function.Consumer;
 import net.kyori.adventure.text.Component;
 import net.minecraft.advancements.critereon.ItemPredicate;
 import net.minecraft.advancements.critereon.MinMaxBounds;
@@ -16,17 +17,21 @@ import net.minecraft.core.component.DataComponentPatch;
 import net.minecraft.core.component.DataComponentPredicate;
 import net.minecraft.core.component.DataComponents;
 import net.minecraft.core.component.PatchedDataComponentMap;
+import net.minecraft.nbt.CompoundTag;
 import net.minecraft.world.item.Item;
+import net.minecraft.world.item.component.CustomData;
 import net.minecraft.world.item.enchantment.EnchantmentHelper;
 import net.minecraft.world.item.enchantment.ItemEnchantments;
 import org.bukkit.Material;
 import org.bukkit.configuration.serialization.DelegateDeserialization;
 import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
+import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
 import org.bukkit.craftbukkit.util.CraftMagicNumbers;
 import org.bukkit.enchantments.Enchantment;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.meta.ItemMeta;
 import org.bukkit.material.MaterialData;
+import org.bukkit.persistence.PersistentDataContainer;
 import org.jetbrains.annotations.NotNull;
 
 @DelegateDeserialization(ItemStack.class)
@@ -159,7 +164,6 @@ public final class CraftItemStack extends ItemStack {
     }
 
     public net.minecraft.world.item.ItemStack handle;
-    private boolean isForInventoryDrop;
 
     /**
      * Mirror
@@ -522,7 +526,7 @@ public final class CraftItemStack extends ItemStack {
     }
     // Paper end
 
-    // Paper start - pdc
+    public static final String PDC_CUSTOM_DATA_KEY = "PublicBukkitValues";
     private net.minecraft.nbt.CompoundTag getPdcTag() {
         if (this.handle == null) {
             return new net.minecraft.nbt.CompoundTag();
@@ -530,7 +534,7 @@ public final class CraftItemStack extends ItemStack {
         final net.minecraft.world.item.component.CustomData customData = this.handle.getOrDefault(DataComponents.CUSTOM_DATA, net.minecraft.world.item.component.CustomData.EMPTY);
         // getUnsafe is OK here because we are only ever *reading* the data so immutability is preserved
         //noinspection deprecation
-        return customData.getUnsafe().getCompound("PublicBukkitValues");
+        return customData.getUnsafe().getCompound(PDC_CUSTOM_DATA_KEY);
     }
 
     private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
@@ -550,7 +554,30 @@ public final class CraftItemStack extends ItemStack {
     public io.papermc.paper.persistence.PersistentDataContainerView getPersistentDataContainer() {
         return this.pdcView;
     }
-    // Paper end - pdc
+
+    @Override
+    public boolean editPersistentDataContainer(final Consumer consumer) {
+        if (this.handle == null || this.handle.isEmpty()) return false;
+
+        final CraftPersistentDataContainer container = new CraftPersistentDataContainer(REGISTRY);
+        CustomData customData = this.handle.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
+        //noinspection deprecation // we copy only the pdc tag
+        final CompoundTag pdcTag = customData.getUnsafe().getCompound(PDC_CUSTOM_DATA_KEY).copy();
+        container.putAll(pdcTag);
+        consumer.accept(container);
+
+        final CompoundTag newPdcTag = container.toTagCompound();
+        if (!newPdcTag.isEmpty()) {
+            customData = customData.update(tag -> tag.put(PDC_CUSTOM_DATA_KEY, newPdcTag));
+        } else if (newPdcTag.isEmpty() && customData.contains(PDC_CUSTOM_DATA_KEY)) {
+            customData = customData.update(tag -> tag.remove(PDC_CUSTOM_DATA_KEY));
+        }
+
+        // mirror CraftMetaItem behavior of clearing component if it's empty.
+        this.handle.set(DataComponents.CUSTOM_DATA, customData.isEmpty() ? null : customData);
+        return true;
+    }
+
     // Paper start - data component API
     @Override
     public  T getData(final io.papermc.paper.datacomponent.DataComponentType.Valued type) {
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index 5bff7a4d6..7d85c554e 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -273,7 +273,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
     static final ItemMetaKeyType MAX_DAMAGE = new ItemMetaKeyType<>(DataComponents.MAX_DAMAGE, "max-damage");
     @Specific(Specific.To.NBT)
     static final ItemMetaKeyType BLOCK_DATA = new ItemMetaKeyType<>(DataComponents.BLOCK_STATE, "BlockStateTag");
-    static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey("PublicBukkitValues");
+    static final ItemMetaKey BUKKIT_CUSTOM_TAG = new ItemMetaKey(CraftItemStack.PDC_CUSTOM_DATA_KEY);
     @Specific(Specific.To.NBT)
     static final ItemMetaKeyType HIDE_ADDITIONAL_TOOLTIP = new ItemMetaKeyType(DataComponents.HIDE_ADDITIONAL_TOOLTIP);
     @Specific(Specific.To.NBT)

From 7bee99714a8e60b870ab8984c456716084563904 Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Sun, 16 Feb 2025 20:14:00 +0100
Subject: [PATCH 118/203] Cleanup damage source a bit (#12106)

---
 .../java/org/bukkit/damage/DamageSource.java  |   4 +
 .../entity/EntityDamageByBlockEvent.java      |   2 +-
 .../entity/EntityDamageByEntityEvent.java     |   6 +-
 .../0016-Moonrise-optimisation-patches.patch  |   4 +-
 .../ServerGamePacketListenerImpl.java.patch   |   8 +-
 .../damagesource/DamageSource.java.patch      | 146 +++++++-----------
 .../damagesource/DamageSources.java.patch     |  50 ------
 .../world/effect/PoisonMobEffect.java.patch   |   2 +-
 .../minecraft/world/entity/Entity.java.patch  |   4 +-
 .../world/entity/Interaction.java.patch       |   4 +-
 .../world/entity/LivingEntity.java.patch      |   4 +-
 .../world/entity/animal/SnowGolem.java.patch  |   2 +-
 .../world/entity/animal/Turtle.java.patch     |   2 +-
 .../world/entity/player/Player.java.patch     |  10 +-
 .../entity/projectile/EvokerFangs.java.patch  |   2 +-
 .../projectile/ThrownEnderpearl.java.patch    |   2 +-
 .../entity/projectile/WitherSkull.java.patch  |   2 +-
 .../world/level/ServerExplosion.java.patch    |   2 +-
 .../world/level/block/BedBlock.java.patch     |   2 +-
 .../world/level/block/CactusBlock.java.patch  |   2 +-
 .../level/block/CampfireBlock.java.patch      |   2 +-
 .../world/level/block/MagmaBlock.java.patch   |   2 +-
 .../block/PointedDripstoneBlock.java.patch    |   2 +-
 .../level/block/RespawnAnchorBlock.java.patch |   2 +-
 .../block/SweetBerryBushBlock.java.patch      |   2 +-
 .../entity/ConduitBlockEntity.java.patch      |   2 +-
 .../craftbukkit/damage/CraftDamageSource.java |  40 ++---
 .../craftbukkit/damage/CraftDamageType.java   |   2 +-
 .../entity/CraftAbstractArrow.java            |   2 +-
 .../bukkit/craftbukkit/entity/CraftArrow.java |   2 +-
 .../craftbukkit/event/CraftEventFactory.java  |  32 ++--
 31 files changed, 135 insertions(+), 215 deletions(-)
 delete mode 100644 paper-server/patches/sources/net/minecraft/world/damagesource/DamageSources.java.patch

diff --git a/paper-api/src/main/java/org/bukkit/damage/DamageSource.java b/paper-api/src/main/java/org/bukkit/damage/DamageSource.java
index 7635610e5..54fa3ebe5 100644
--- a/paper-api/src/main/java/org/bukkit/damage/DamageSource.java
+++ b/paper-api/src/main/java/org/bukkit/damage/DamageSource.java
@@ -51,6 +51,8 @@ public interface DamageSource {
      * be present if an entity did not cause the damage.
      *
      * @return the location, or null if none
+     * @apiNote the world of the location might be null for positioned-only damage source
+     * not caused by any entity
      */
     @Nullable
     public Location getDamageLocation();
@@ -66,6 +68,8 @@ public interface DamageSource {
      * returned.
      *
      * @return the source of the location or null.
+     * @apiNote the world of the location might be null for positioned-only damage source
+     * not caused by any entity
      */
     @Nullable
     public Location getSourceLocation();
diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
index 971093bd2..35aa2cbc5 100644
--- a/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
+++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
@@ -23,7 +23,7 @@ public class EntityDamageByBlockEvent extends EntityDamageEvent {
 
     @Deprecated(since = "1.20.4", forRemoval = true)
     public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) {
-        this(damager, (damager != null) ? damager.getState() : null, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), damage);
+        this(damager, (damager != null) ? damager.getState() : null, damagee, cause, DamageSource.builder(DamageType.GENERIC).build(), damage);
     }
 
     public EntityDamageByBlockEvent(@Nullable final Block damager, @Nullable final BlockState damagerState, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, final double damage) {
diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
index 31a36ed3b..2a36d5b18 100644
--- a/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
+++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java
@@ -17,7 +17,7 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent {
 
     @Deprecated(since = "1.20.4", forRemoval = true)
     public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) {
-        this(damager, damagee, cause, DamageSource.builder(DamageType.GENERIC).withCausingEntity(damager).withDirectEntity(damager).build(), damage);
+        this(damager, damagee, cause, DamageSource.builder(DamageType.GENERIC).build(), damage);
     }
 
     @Deprecated
@@ -29,7 +29,7 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent {
 
     @Deprecated(since = "1.20.4", forRemoval = true)
     public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map modifiers, @NotNull final Map> modifierFunctions) {
-        this(damager, damagee, cause, DamageSource.builder(DamageType.GENERIC).withCausingEntity(damager).withDirectEntity(damager).build(), modifiers, modifierFunctions);
+        this(damager, damagee, cause, DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions);
     }
 
     @Deprecated
@@ -65,7 +65,7 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent {
      * {@inheritDoc}
      * 

* The {@link DamageSource#getDirectEntity()} may be different from the {@link #getDamager()} - * if the Minecraft damage source did not originally include an damager entity, but one was included + * if the damage source did not originally include a damager entity, but one was included * for this event {@link #getDamager()}. */ @Override diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 95220d300..1d2ef43ca 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -28372,7 +28372,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 449c43286e1483b69667c626b234529a16c19ee1..b268b428ec8f2e50737e1dd5cc705c537322433c 100644 +index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d05190eb6 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -30418,7 +30418,7 @@ index 2709803b9266ff4a2034d83321cd0ba4e30fc0aa..26c8c1e5598daf3550aef05b12218c47 ChunkAccess getChunk(int x, int z, ChunkStatus chunkStatus, boolean requireChunk); diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index 3619509d51ebd2e5e36fe4b67e76c94a8d272d1b..7b132c55caf9d3c3df3b0a123f4b5bfc7ae35984 100644 +index 155bf7ccff5c1332fceda2598342bb03624608ff..c4485f28def66264846a436cfba7bddccb66b82e 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -63,6 +63,249 @@ public class ServerExplosion implements Explosion { 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 e485e7c21..8589a3b4e 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 @@ -1119,7 +1119,13 @@ this.player.drop(false); } -@@ -1125,8 +_,34 @@ +@@ -1120,13 +_,39 @@ + + return; + case RELEASE_USE_ITEM: +- this.player.releaseUsingItem(); ++ if (this.player.getUseItem() == this.player.getItemInHand(this.player.getUsedItemHand())) this.player.releaseUsingItem(); // Paper - validate use item before processing release + return; case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: diff --git a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch index 00eaac621..d530c5c2c 100644 --- a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch @@ -1,129 +1,95 @@ --- a/net/minecraft/world/damagesource/DamageSource.java +++ b/net/minecraft/world/damagesource/DamageSource.java -@@ -20,6 +_,107 @@ +@@ -20,6 +_,92 @@ private final Entity directEntity; @Nullable private final Vec3 damageSourcePosition; + // CraftBukkit start + @Nullable -+ private org.bukkit.block.Block directBlock; // The block that caused the damage. damageSourcePosition is not used for all block damages ++ private org.bukkit.event.entity.EntityDamageEvent.DamageCause knownCause; // When the damage event cause is known by the context of the call rather than the damage source data + @Nullable -+ private org.bukkit.block.BlockState directBlockState; // The block state of the block relevant to this damage source -+ private boolean sweep = false; -+ private boolean melting = false; -+ private boolean poison = false; ++ private Entity eventEntityDamager = null; // Relevant entity set when the game doesn't normally set a causingEntity/directEntity + @Nullable -+ private Entity customEventDamager = null; // This field is a helper for when causing entity damage is not set by vanilla // Paper - fix DamageSource API -+ -+ public DamageSource sweep() { -+ this.sweep = true; -+ return this; -+ } -+ -+ public boolean isSweep() { -+ return this.sweep; -+ } -+ -+ public DamageSource melting() { -+ this.melting = true; -+ return this; -+ } -+ -+ public boolean isMelting() { -+ return this.melting; -+ } -+ -+ public DamageSource poison() { -+ this.poison = true; -+ return this; -+ } -+ -+ public boolean isPoison() { -+ return this.poison; -+ } -+ -+ // Paper start - fix DamageSource API ++ private org.bukkit.block.Block eventBlockDamager; // Relevant block set. damageSourcePosition is only used for bad respawn point explosion or custom damage + @Nullable -+ public Entity getCustomEventDamager() { -+ return (this.customEventDamager != null) ? this.customEventDamager : this.directEntity; ++ private org.bukkit.block.BlockState fromBlockSnapshot; // Captured block snapshot when the eventBlockDamager is not relevant (e.g. for bad respawn point explosions the block is already removed) ++ private boolean critical; // Supports arrows and sweeping damage ++ ++ public DamageSource knownCause(final org.bukkit.event.entity.EntityDamageEvent.DamageCause cause) { ++ final DamageSource damageSource = this.copy(); ++ damageSource.knownCause = cause; ++ return damageSource; + } + -+ public DamageSource customEventDamager(Entity entity) { ++ @Nullable ++ public org.bukkit.event.entity.EntityDamageEvent.DamageCause knownCause() { ++ return this.knownCause; ++ } ++ ++ @Nullable ++ public Entity eventEntityDamager() { ++ return this.eventEntityDamager; ++ } ++ ++ public DamageSource eventEntityDamager(final Entity entity) { + if (this.directEntity != null) { -+ throw new IllegalStateException("Cannot set custom event damager when direct entity is already set (report a bug to Paper)"); ++ throw new IllegalStateException("Cannot set an event damager when a direct entity is already set (report a bug to Paper)"); + } -+ DamageSource damageSource = this.cloneInstance(); -+ damageSource.customEventDamager = entity; -+ // Paper end - fix DamageSource API ++ final DamageSource damageSource = this.copy(); ++ damageSource.eventEntityDamager = entity; + return damageSource; + } + + @Nullable -+ public org.bukkit.block.Block getDirectBlock() { -+ return this.directBlock; ++ public org.bukkit.block.Block eventBlockDamager() { ++ return this.eventBlockDamager; + } + -+ public DamageSource directBlock(@Nullable net.minecraft.world.level.Level world, @Nullable net.minecraft.core.BlockPos blockPosition) { -+ if (blockPosition == null || world == null) { ++ public DamageSource eventBlockDamager(final @Nullable net.minecraft.world.level.LevelAccessor level, final @Nullable net.minecraft.core.BlockPos pos) { ++ if (pos == null) { + return this; + } -+ return this.directBlock(org.bukkit.craftbukkit.block.CraftBlock.at(world, blockPosition)); -+ } + -+ public DamageSource directBlock(@Nullable org.bukkit.block.Block block) { -+ if (block == null) { -+ return this; -+ } -+ // Cloning the instance lets us return unique instances of DamageSource without affecting constants defined in DamageSources -+ DamageSource damageSource = this.cloneInstance(); -+ damageSource.directBlock = block; ++ final DamageSource damageSource = this.copy(); ++ damageSource.eventBlockDamager = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); + return damageSource; + } + + @Nullable -+ public org.bukkit.block.BlockState getDirectBlockState() { -+ return this.directBlockState; ++ public org.bukkit.block.BlockState causingBlockSnapshot() { ++ return this.fromBlockSnapshot; + } + -+ public DamageSource directBlockState(@Nullable org.bukkit.block.BlockState blockState) { -+ if (blockState == null) { -+ return this; ++ public DamageSource causingBlockSnapshot(final @Nullable org.bukkit.block.BlockState blockState) { ++ if (this.eventBlockDamager != null) { ++ throw new IllegalStateException("Cannot set a block snapshot when an event block damager is already set (report a bug to Paper)"); + } -+ // Cloning the instance lets us return unique instances of DamageSource without affecting constants defined in DamageSources -+ DamageSource damageSource = this.cloneInstance(); -+ damageSource.directBlockState = blockState; ++ final DamageSource damageSource = this.copy(); ++ damageSource.fromBlockSnapshot = blockState; + return damageSource; + } + -+ private DamageSource cloneInstance() { -+ DamageSource damageSource = new DamageSource(this.type, this.directEntity, this.causingEntity, this.damageSourcePosition); -+ damageSource.directBlock = this.getDirectBlock(); -+ damageSource.directBlockState = this.getDirectBlockState(); -+ damageSource.sweep = this.isSweep(); -+ damageSource.poison = this.isPoison(); -+ damageSource.melting = this.isMelting(); ++ public boolean isCritical() { ++ return this.critical; ++ } ++ ++ public DamageSource critical() { ++ final DamageSource damageSource = this.copy(); ++ damageSource.critical = true; ++ return damageSource; ++ } ++ ++ // Cloning the instance lets us return unique instances of DamageSource without affecting constants defined in DamageSources ++ private DamageSource copy() { ++ final DamageSource damageSource = new DamageSource(this.type, this.directEntity, this.causingEntity, this.damageSourcePosition); ++ damageSource.knownCause = this.knownCause; ++ damageSource.eventEntityDamager = this.eventEntityDamager; ++ damageSource.eventBlockDamager = this.eventBlockDamager; ++ damageSource.fromBlockSnapshot = this.fromBlockSnapshot; ++ damageSource.critical = this.critical; + return damageSource; + } + // CraftBukkit end @Override public String toString() { -@@ -134,4 +_,18 @@ - public Holder typeHolder() { - return this.type; - } -+ -+ // Paper start - add critical damage API -+ private boolean critical; -+ public boolean isCritical() { -+ return this.critical; -+ } -+ public DamageSource critical() { -+ return this.critical(true); -+ } -+ public DamageSource critical(boolean critical) { -+ this.critical = critical; -+ return this; -+ } -+ // Paper end - add critical damage API - } diff --git a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSources.java.patch b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSources.java.patch deleted file mode 100644 index f13f6629d..000000000 --- a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSources.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/net/minecraft/world/damagesource/DamageSources.java -+++ b/net/minecraft/world/damagesource/DamageSources.java -@@ -42,9 +_,15 @@ - private final DamageSource stalagmite; - private final DamageSource outsideBorder; - private final DamageSource genericKill; -+ // CraftBukkit start -+ private final DamageSource melting; -+ private final DamageSource poison; - - public DamageSources(RegistryAccess registry) { - this.damageTypes = registry.lookupOrThrow(Registries.DAMAGE_TYPE); -+ this.melting = this.source(DamageTypes.ON_FIRE).melting(); -+ this.poison = this.source(DamageTypes.MAGIC).poison(); -+ // CraftBukkit end - this.inFire = this.source(DamageTypes.IN_FIRE); - this.campfire = this.source(DamageTypes.CAMPFIRE); - this.lightningBolt = this.source(DamageTypes.LIGHTNING_BOLT); -@@ -84,6 +_,16 @@ - return new DamageSource(this.damageTypes.getOrThrow(damageTypeKey), causingEntity, directEntity); - } - -+ // CraftBukkit start -+ public DamageSource melting() { -+ return this.melting; -+ } -+ -+ public DamageSource poison() { -+ return this.poison; -+ } -+ // CraftBukkit end -+ - public DamageSource inFire() { - return this.inFire; - } -@@ -261,7 +_,13 @@ - } - - public DamageSource badRespawnPointExplosion(Vec3 position) { -- return new DamageSource(this.damageTypes.getOrThrow(DamageTypes.BAD_RESPAWN_POINT), position); -+ // CraftBukkit start -+ return this.badRespawnPointExplosion(position, null); -+ } -+ -+ public DamageSource badRespawnPointExplosion(Vec3 position, org.bukkit.block.BlockState blockState) { -+ return new DamageSource(this.damageTypes.getOrThrow(DamageTypes.BAD_RESPAWN_POINT), position).directBlockState(blockState); -+ // CraftBukkit end - } - - public DamageSource outOfBorder() { diff --git a/paper-server/patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch index 66061ffa2..756bcf1d8 100644 --- a/paper-server/patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/effect/PoisonMobEffect.java.patch @@ -5,7 +5,7 @@ public boolean applyEffectTick(ServerLevel level, LivingEntity entity, int amplifier) { if (entity.getHealth() > 1.0F) { - entity.hurtServer(level, entity.damageSources().magic(), 1.0F); -+ entity.hurtServer(level, entity.damageSources().poison(), 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON ++ entity.hurtServer(level, entity.damageSources().magic().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.POISON), 1.0F); // CraftBukkit } return true; 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 691432fd2..9340b5b32 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 @@ -459,7 +459,7 @@ + // CraftBukkit end if (this.level() instanceof ServerLevel serverLevel - && this.hurtServer(serverLevel, this.damageSources().lava(), 4.0F) -+ && this.hurtServer(serverLevel, this.damageSources().lava().directBlock(this.level, this.lastLavaContact), 4.0F) // CraftBukkit - we also don't throw an event unless the object in lava is living, to save on some event calls ++ && this.hurtServer(serverLevel, this.damageSources().lava().eventBlockDamager(this.level, this.lastLavaContact), 4.0F) // CraftBukkit - we also don't throw an event unless the object in lava is living, to save on some event calls && this.shouldPlayLavaHurtSound() && !this.isSilent()) { serverLevel.playSound( @@ -1300,7 +1300,7 @@ + return; + } + -+ if (!this.hurtServer(level, this.damageSources().lightningBolt().customEventDamager(lightning), 5.0F)) { // Paper - fix DamageSource API ++ if (!this.hurtServer(level, this.damageSources().lightningBolt().eventEntityDamager(lightning), 5.0F)) { // Paper - fix DamageSource API + return; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch index 3d9857c80..914667d8d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch @@ -5,7 +5,7 @@ public boolean skipAttackInteraction(Entity entity) { if (entity instanceof Player player) { + // CraftBukkit start -+ DamageSource source = player.damageSources().playerAttack(player); ++ DamageSource source = player.damageSources().generic().eventEntityDamager(entity); + org.bukkit.event.entity.EntityDamageEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNonLivingEntityDamageEvent(this, source, 1.0F, false); + if (event.isCancelled()) { + return true; @@ -14,7 +14,7 @@ this.attack = new Interaction.PlayerAction(player.getUUID(), this.level().getGameTime()); if (player instanceof ServerPlayer serverPlayer) { - CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(serverPlayer, this, player.damageSources().generic(), 1.0F, 1.0F, false); -+ CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(serverPlayer, this, player.damageSources().generic(), 1.0F, (float) event.getFinalDamage(), false); // CraftBukkit // Paper - use correct source and fix taken/dealt param order ++ CriteriaTriggers.PLAYER_HURT_ENTITY.trigger(serverPlayer, this, source, 1.0F, (float) event.getFinalDamage(), false); // CraftBukkit // Paper - use correct source and fix taken/dealt param order } return !this.getResponse(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index bca5d0ef6..8015fbab2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -678,7 +678,7 @@ + event.setCancelled(itemStack == null); + this.level().getCraftServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { -+ // Set death protection to null as the event was cancelled. Prevent any attempt at ressurection. ++ // Set death protection to null as the event was cancelled. Prevent any attempt at resurrection. + deathProtection = null; + } else { + if (!itemInHand.isEmpty() && itemStack != null) { // Paper - only reduce item if actual totem was found @@ -691,7 +691,7 @@ - if (this instanceof ServerPlayer serverPlayer) { + } + // Paper start - fix NPE when pre-cancelled EntityResurrectEvent is uncancelled -+ // restore the previous behavior in that case by defaulting to vanillas totem of undying efect ++ // restore the previous behavior in that case by defaulting to vanillas totem of undying effect + if (deathProtection == null) { + deathProtection = DeathProtection.TOTEM_OF_UNDYING; + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch index e647b528c..ab7a9f125 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch @@ -5,7 +5,7 @@ if (this.level() instanceof ServerLevel serverLevel) { if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) { - this.hurtServer(serverLevel, this.damageSources().onFire(), 1.0F); -+ this.hurtServer(serverLevel, this.damageSources().melting(), 1.0F); // CraftBukkit - DamageSources.ON_FIRE -> CraftEventFactory.MELTING ++ this.hurtServer(serverLevel, this.damageSources().onFire().knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.MELTING), 1.0F); // CraftBukkit } if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch index 741323b5b..608d6617d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch @@ -15,7 +15,7 @@ @Override public void thunderHit(ServerLevel level, LightningBolt lightning) { - this.hurtServer(level, this.damageSources().lightningBolt(), Float.MAX_VALUE); -+ this.hurtServer(level, this.damageSources().lightningBolt().customEventDamager(lightning), Float.MAX_VALUE); // CraftBukkit // Paper - fix DamageSource API ++ this.hurtServer(level, this.damageSources().lightningBolt().eventEntityDamager(lightning), Float.MAX_VALUE); // CraftBukkit // Paper - fix DamageSource API } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch index 5e8dba7c7..dd2387ae9 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -314,7 +314,7 @@ && !this.isSprinting(); + flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits if (flag2) { -+ damageSource = damageSource.critical(true); // Paper start - critical damage API ++ damageSource = damageSource.critical(); // Paper - critical damage API f *= 1.5F; } @@ -342,12 +342,14 @@ } if (flag3) { -@@ -1212,43 +_,62 @@ +@@ -1212,43 +_,64 @@ && (!(livingEntity2 instanceof ArmorStand) || !((ArmorStand)livingEntity2).isMarker()) && this.distanceToSqr(livingEntity2) < 9.0) { float f6 = this.getEnchantedDamage(livingEntity2, f5, damageSource) * attackStrengthScale; -+ // CraftBukkit start - Only apply knockback if the damage hits -+ if (!livingEntity2.hurtServer((ServerLevel) this.level(), this.damageSources().playerAttack(this).sweep().critical(flag2), f6)) { // Paper - add critical damage API ++ // CraftBukkit start - Only apply knockback if the event is not cancelled ++ livingEntity2.lastDamageCancelled = false; ++ livingEntity2.hurtServer((ServerLevel) this.level(), damageSource.knownCause(org.bukkit.event.entity.EntityDamageEvent.DamageCause.ENTITY_SWEEP_ATTACK), f6); ++ if (livingEntity2.lastDamageCancelled) { + continue; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch index e980aa385..a28c202eb 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch @@ -14,7 +14,7 @@ if (target.isAlive() && !target.isInvulnerable() && target != owner) { if (owner == null) { - target.hurt(this.damageSources().magic(), 6.0F); -+ target.hurt(this.damageSources().magic().customEventDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API ++ target.hurt(this.damageSources().magic().eventEntityDamager(this), 6.0F); // CraftBukkit // Paper - fix DamageSource API } else { if (owner.isAlliedTo(target)) { return; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch index 8fdaf1cd3..10a6491ba 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch @@ -40,7 +40,7 @@ serverPlayer1.resetFallDistance(); serverPlayer1.resetCurrentImpulseContext(); - serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl(), 5.0F); -+ serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().customEventDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API ++ serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API } this.playSound(serverLevel, vec3); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch index d323b77c2..2eef3589e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch @@ -10,7 +10,7 @@ } } else { - flag = var8.hurtServer(serverLevel, this.damageSources().magic(), 5.0F); -+ flag = var8.hurtServer(serverLevel, this.damageSources().magic().customEventDamager(this), 5.0F); // Paper - Fire EntityDamageByEntityEvent for unowned wither skulls // Paper - fix DamageSource API ++ flag = var8.hurtServer(serverLevel, this.damageSources().magic().eventEntityDamager(this), 5.0F); // Paper - Fire EntityDamageByEntityEvent for unowned wither skulls // Paper - fix DamageSource API } if (flag && var8 instanceof LivingEntity livingEntityx) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch index 263bafc98..a7b3faa86 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch @@ -175,7 +175,7 @@ + this.yield = event.getYield(); + } else { + org.bukkit.block.Block block = location.getBlock(); -+ org.bukkit.block.BlockState blockState = (this.damageSource.getDirectBlockState() != null) ? this.damageSource.getDirectBlockState() : block.getState(); ++ org.bukkit.block.BlockState blockState = (this.damageSource.causingBlockSnapshot() != null) ? this.damageSource.causingBlockSnapshot() : block.getState(); + BlockExplodeEvent event = CraftEventFactory.callBlockExplodeEvent(block, blockState, blockList, this.yield, this.getBlockInteraction()); + this.wasCanceled = event.isCancelled(); + bukkitBlocks = event.blockList(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch index f56e52852..1b12bd9f7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch @@ -59,7 +59,7 @@ + } + + Vec3 center = pos.getCenter(); -+ level.explode(null, level.damageSources().badRespawnPointExplosion(center, blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state ++ level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state + return InteractionResult.SUCCESS_SERVER; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch index af19e96da..3690ad3d1 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch @@ -27,7 +27,7 @@ protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { - entity.hurt(level.damageSources().cactus(), 1.0F); + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent -+ entity.hurt(level.damageSources().cactus().directBlock(level, pos), 1.0F); // CraftBukkit ++ entity.hurt(level.damageSources().cactus().eventBlockDamager(level, pos), 1.0F); // CraftBukkit } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch index 0663b2c49..df0ab0b58 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch @@ -7,7 +7,7 @@ + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (state.getValue(LIT) && entity instanceof LivingEntity) { - entity.hurt(level.damageSources().campfire(), this.fireDamage); -+ entity.hurt(level.damageSources().campfire().directBlock(level, pos), (float) this.fireDamage); // CraftBukkit ++ entity.hurt(level.damageSources().campfire().eventBlockDamager(level, pos), (float) this.fireDamage); // CraftBukkit } super.entityInside(state, level, pos, entity); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch index ae7d0a7fd..a3fec4f2d 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch @@ -5,7 +5,7 @@ public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) { if (!entity.isSteppingCarefully() && entity instanceof LivingEntity) { - entity.hurt(level.damageSources().hotFloor(), 1.0F); -+ entity.hurt(level.damageSources().hotFloor().directBlock(level, pos), 1.0F); // CraftBukkit ++ entity.hurt(level.damageSources().hotFloor().eventBlockDamager(level, pos), 1.0F); // CraftBukkit } super.stepOn(level, pos, state, entity); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch index 98e5a6861..13c6c6845 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch @@ -17,7 +17,7 @@ public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) { if (state.getValue(TIP_DIRECTION) == Direction.UP && state.getValue(THICKNESS) == DripstoneThickness.TIP) { - entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite()); -+ entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite().directBlock(level, pos)); // CraftBukkit ++ entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite().eventBlockDamager(level, pos)); // CraftBukkit } else { super.fallOn(level, state, pos, entity, fallDistance); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch index 17ec642ed..c66c883b7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch @@ -31,7 +31,7 @@ Vec3 center = pos2.getCenter(); level.explode( - null, level.damageSources().badRespawnPointExplosion(center), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK -+ null, level.damageSources().badRespawnPointExplosion(center, blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state ++ null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state ); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch index a22888513..ea6d6c6cc 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SweetBerryBushBlock.java.patch @@ -24,7 +24,7 @@ double abs1 = Math.abs(vec3.z()); if (abs >= 0.003F || abs1 >= 0.003F) { - entity.hurtServer(serverLevel, level.damageSources().sweetBerryBush(), 1.0F); -+ entity.hurtServer(serverLevel, level.damageSources().sweetBerryBush().directBlock(level, pos), 1.0F); // CraftBukkit ++ entity.hurtServer(serverLevel, level.damageSources().sweetBerryBush().eventBlockDamager(level, pos), 1.0F); // CraftBukkit } } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch index 31b86a4f4..226211f28 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch @@ -56,7 +56,7 @@ - if (blockEntity.destroyTarget != null) { + if (damageTarget && blockEntity.destroyTarget != null) { // CraftBukkit -+ if (blockEntity.destroyTarget.hurtServer((net.minecraft.server.level.ServerLevel) level, level.damageSources().magic().directBlock(level, pos), 4.0F)) // CraftBukkit ++ if (blockEntity.destroyTarget.hurtServer((net.minecraft.server.level.ServerLevel) level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit level.playSound( null, blockEntity.destroyTarget.getX(), diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java b/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java index 7df86e712..f2a6c4fdd 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageSource.java @@ -1,10 +1,10 @@ package org.bukkit.craftbukkit.damage; import java.util.Objects; +import net.minecraft.Optionull; import net.minecraft.world.phys.Vec3; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.block.Block; import org.bukkit.craftbukkit.entity.CraftEntity; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.damage.DamageSource; @@ -26,12 +26,7 @@ public class CraftDamageSource implements DamageSource { } public World getCausingEntityWorld() { - org.bukkit.entity.Entity causingEntity = this.getCausingEntity(); - return causingEntity != null ? causingEntity.getWorld() : null; - } - - public Block getDirectBlock() { - return this.getHandle().getDirectBlock(); + return Optionull.map(this.getCausingEntity(), Entity::getWorld); } @Override @@ -41,26 +36,22 @@ public class CraftDamageSource implements DamageSource { @Override public org.bukkit.entity.Entity getCausingEntity() { - net.minecraft.world.entity.Entity entity = this.getHandle().getEntity(); // Paper - fix DamageSource API - revert to vanilla - return (entity != null) ? entity.getBukkitEntity() : null; + return Optionull.map(this.getHandle().getEntity(), net.minecraft.world.entity.Entity::getBukkitEntity); } @Override public org.bukkit.entity.Entity getDirectEntity() { - net.minecraft.world.entity.Entity entity = this.getHandle().getDirectEntity(); // Paper - fix DamageSource API - return (entity != null) ? entity.getBukkitEntity() : null; + return Optionull.map(this.getHandle().getDirectEntity(), net.minecraft.world.entity.Entity::getBukkitEntity); } @Override public Location getDamageLocation() { - Vec3 vec3D = this.getHandle().sourcePositionRaw(); - return (vec3D != null) ? CraftLocation.toBukkit(vec3D, this.getCausingEntityWorld()) : null; + return Optionull.map(this.getHandle().sourcePositionRaw(), sourcePos -> CraftLocation.toBukkit(sourcePos, this.getCausingEntityWorld())); } @Override public Location getSourceLocation() { - Vec3 vec3D = this.getHandle().getSourcePosition(); - return (vec3D != null) ? CraftLocation.toBukkit(vec3D, this.getCausingEntityWorld()) : null; + return Optionull.map(this.getHandle().getSourcePosition(), sourcePos -> CraftLocation.toBukkit(sourcePos, this.getCausingEntityWorld())); } @Override @@ -70,7 +61,7 @@ public class CraftDamageSource implements DamageSource { @Override public float getFoodExhaustion() { - return this.damageType.getExhaustion(); + return this.getHandle().getFoodExhaustion(); } @Override @@ -84,28 +75,27 @@ public class CraftDamageSource implements DamageSource { return true; } - if (!(obj instanceof DamageSource)) { + if (!(obj instanceof DamageSource other)) { return false; } - DamageSource other = (DamageSource) obj; return Objects.equals(this.getDamageType(), other.getDamageType()) && Objects.equals(this.getCausingEntity(), other.getCausingEntity()) - && Objects.equals(this.getDirectEntity(), other.getDirectEntity()) && Objects.equals(this.getDamageLocation(), other.getDamageLocation()); + && Objects.equals(this.getDirectEntity(), other.getDirectEntity()) && Objects.equals(this.getDamageLocation(), other.getDamageLocation()); } @Override public int hashCode() { int result = 1; result = 31 * result + this.damageType.hashCode(); - result = 31 * result + (this.getCausingEntity() != null ? this.getCausingEntity().hashCode() : 0); - result = 31 * result + (this.getDirectEntity() != null ? this.getDirectEntity().hashCode() : 0); - result = 31 * result + (this.getDamageLocation() != null ? this.getDamageLocation().hashCode() : 0); + result = 31 * result + Objects.hashCode(this.getCausingEntity()); + result = 31 * result + Objects.hashCode(this.getDirectEntity()); + result = 31 * result + Objects.hashCode(this.getDamageLocation()); return result; } @Override public String toString() { - return "DamageSource{damageType=" + this.getDamageType() + ",causingEntity=" + this.getCausingEntity() + ",directEntity=" + this.getDirectEntity() + ",damageLocation=" + this.getDamageLocation() + "}"; + return "DamageSource{damageType=" + this.getDamageType() + ", causingEntity=" + this.getCausingEntity() + ", directEntity=" + this.getDirectEntity() + ", damageLocation=" + this.getDamageLocation() + "}"; } public static DamageSource buildFromBukkit(DamageType damageType, Entity causingEntity, Entity directEntity, Location damageLocation) { @@ -121,8 +111,8 @@ public class CraftDamageSource implements DamageSource { nmsDirectEntity = craftDirectEntity.getHandle(); } - Vec3 vec3D = (damageLocation == null) ? null : CraftLocation.toVec3D(damageLocation); + Vec3 sourcePos = (damageLocation == null) ? null : CraftLocation.toVec3D(damageLocation); - return new CraftDamageSource(new net.minecraft.world.damagesource.DamageSource(holderDamageType, nmsDirectEntity, nmsCausingEntity, vec3D)); + return new CraftDamageSource(new net.minecraft.world.damagesource.DamageSource(holderDamageType, nmsDirectEntity, nmsCausingEntity, sourcePos)); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java index 335077585..d907bad23 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/damage/CraftDamageType.java @@ -58,7 +58,7 @@ public class CraftDamageType implements DamageType, Handleable modifiers, Map> modifierFunctions, boolean cancelled) { CraftDamageSource bukkitDamageSource = new CraftDamageSource(source); - final Entity damager = source.getCustomEventDamager(); // Paper - fix DamageSource API + final Entity damager = source.eventEntityDamager() != null ? source.eventEntityDamager() : source.getDirectEntity(); // Paper - fix DamageSource API if (source.is(DamageTypeTags.IS_EXPLOSION)) { if (damager == null) { - return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); + return CraftEventFactory.callEntityDamageEvent(source.eventBlockDamager(), source.causingBlockSnapshot(), entity, DamageCause.BLOCK_EXPLOSION, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } DamageCause damageCause = (damager.getBukkitEntity() instanceof org.bukkit.entity.TNTPrimed) ? DamageCause.BLOCK_EXPLOSION : DamageCause.ENTITY_EXPLOSION; return CraftEventFactory.callEntityDamageEvent(damager, entity, damageCause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API } else if (damager != null || source.getDirectEntity() != null) { - DamageCause cause = (source.isSweep()) ? DamageCause.ENTITY_SWEEP_ATTACK : DamageCause.ENTITY_ATTACK; + DamageCause cause = DamageCause.ENTITY_ATTACK; - if (damager instanceof net.minecraft.world.entity.projectile.Projectile) { + if (source.knownCause() != null) { + cause = source.knownCause(); + } else if (damager instanceof net.minecraft.world.entity.projectile.Projectile) { if (damager.getBukkitEntity() instanceof ThrownPotion) { cause = DamageCause.MAGIC; } else if (damager.getBukkitEntity() instanceof Projectile) { @@ -1126,12 +1128,14 @@ public class CraftEventFactory { return CraftEventFactory.callEntityDamageEvent(damager, entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled, source.isCritical()); // Paper - add critical damage API } else if (source.is(DamageTypes.FELL_OUT_OF_WORLD)) { - return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled); + return CraftEventFactory.callEntityDamageEvent(source.eventBlockDamager(), source.causingBlockSnapshot(), entity, DamageCause.VOID, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } else if (source.is(DamageTypes.LAVA)) { - return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, DamageCause.LAVA, bukkitDamageSource, modifiers, modifierFunctions, cancelled); - } else if (source.getDirectBlock() != null) { + return CraftEventFactory.callEntityDamageEvent(source.eventBlockDamager(), source.causingBlockSnapshot(), entity, DamageCause.LAVA, bukkitDamageSource, modifiers, modifierFunctions, cancelled); + } else if (source.eventBlockDamager() != null) { DamageCause cause; - if (source.is(DamageTypes.CACTUS) || source.is(DamageTypes.SWEET_BERRY_BUSH) || source.is(DamageTypes.STALAGMITE) || source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_ANVIL)) { + if (source.knownCause() != null) { + cause = source.knownCause(); + } else if (source.is(DamageTypes.CACTUS) || source.is(DamageTypes.SWEET_BERRY_BUSH) || source.is(DamageTypes.STALAGMITE) || source.is(DamageTypes.FALLING_STALACTITE) || source.is(DamageTypes.FALLING_ANVIL)) { cause = DamageCause.CONTACT; } else if (source.is(DamageTypes.HOT_FLOOR)) { cause = DamageCause.HOT_FLOOR; @@ -1142,13 +1146,15 @@ public class CraftEventFactory { } else if (source.is(DamageTypes.CAMPFIRE)) { cause = DamageCause.CAMPFIRE; } else { - throw new IllegalStateException(String.format("Unhandled damage of %s by %s from %s [%s]", entity, source.getDirectBlock(), source.getMsgId(), source.typeHolder().getRegisteredName())); + cause = DamageCause.CUSTOM; } - return CraftEventFactory.callEntityDamageEvent(source.getDirectBlock(), source.getDirectBlockState(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled); + return CraftEventFactory.callEntityDamageEvent(source.eventBlockDamager(), source.causingBlockSnapshot(), entity, cause, bukkitDamageSource, modifiers, modifierFunctions, cancelled); } DamageCause cause; - if (source.is(DamageTypes.IN_FIRE)) { + if (source.knownCause() != null) { + cause = source.knownCause(); + } else if (source.is(DamageTypes.IN_FIRE)) { cause = DamageCause.FIRE; } else if (source.is(DamageTypes.STARVE)) { cause = DamageCause.STARVATION; @@ -1160,10 +1166,6 @@ public class CraftEventFactory { cause = DamageCause.DROWNING; } else if (source.is(DamageTypes.ON_FIRE)) { cause = DamageCause.FIRE_TICK; - } else if (source.isMelting()) { - cause = DamageCause.MELTING; - } else if (source.isPoison()) { - cause = DamageCause.POISON; } else if (source.is(DamageTypes.MAGIC)) { cause = DamageCause.MAGIC; } else if (source.is(DamageTypes.FALL)) { From b9023b5dc3dbc2f9d19898f73e503bddde364bcf Mon Sep 17 00:00:00 2001 From: Chaosdave34 <48226277+Chaosdave34@users.noreply.github.com> Date: Sun, 16 Feb 2025 20:19:28 +0100 Subject: [PATCH 119/203] Add EntityAttemptSmashAttackEvent (#12113) --- .../entity/EntityAttemptSmashAttackEvent.java | 103 ++++++++++++++++++ .../minecraft/world/item/MaceItem.java.patch | 17 +++ 2 files changed, 120 insertions(+) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java create mode 100644 paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java new file mode 100644 index 000000000..007b61d01 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityAttemptSmashAttackEvent.java @@ -0,0 +1,103 @@ +package io.papermc.paper.event.entity; + +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called when an entity attempts to perform a smash attack. + */ +@NullMarked +public class EntityAttemptSmashAttackEvent extends EntityEvent { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final LivingEntity target; + private final ItemStack weapon; + private final boolean originalResult; + private Result result = Result.DEFAULT; + + @ApiStatus.Internal + public EntityAttemptSmashAttackEvent( + final LivingEntity attacker, + final LivingEntity target, + final ItemStack weapon, + final boolean originalResult + ) { + super(attacker); + this.target = target; + this.weapon = weapon; + this.originalResult = originalResult; + } + + /** + * Yields the target of the attempted smash attack. + * + * @return the target entity + */ + public LivingEntity getTarget() { + return target; + } + + /** + * Yields a copy of the itemstack used in the smash attack attempt. + * + * @return the itemstack + */ + public ItemStack getWeapon() { + return weapon.clone(); + } + + /** + * Yields the original result the server computed. + * + * @return {@code true} if this attempt would have been successful by vanilla's logic, {@code false} otherwise. + */ + public boolean getOriginalResult() { + return originalResult; + } + + /** + * Yields the effective result of this event. + * The result may take one of three values: + * + *

    + *
  • {@link Result#ALLOW}: The attempt will succeed.
  • + *
  • {@link Result#DENY}: The attempt will fail.
  • + *
  • {@link Result#DEFAULT}: The attempt will succeed if {@link #getOriginalResult()} is {@code true} and fail otherwise.
  • + *
+ * + * @return the result. + */ + public Result getResult() { + return this.result; + } + + /** + * Configures a new result for this event. + * The passes result may take one of three values: + * + *
    + *
  • {@link Result#ALLOW}: The attempt will succeed.
  • + *
  • {@link Result#DENY}: The attempt will fail.
  • + *
  • {@link Result#DEFAULT}: The attempt will succeed if {@link #getOriginalResult()} is {@code true} and fail otherwise.
  • + *
+ * + * @param result the new result of the event. + */ + public void setResult(final Result result) { + this.result = result; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch new file mode 100644 index 000000000..cfeffcdd8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/item/MaceItem.java ++++ b/net/minecraft/world/item/MaceItem.java +@@ -61,7 +_,13 @@ + + @Override + public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) { +- if (canSmashAttack(attacker)) { ++ // Paper start - Add EntityAttemptSmashAttackEvent ++ final boolean canSmashAttack = canSmashAttack(attacker); ++ io.papermc.paper.event.entity.EntityAttemptSmashAttackEvent event = new io.papermc.paper.event.entity.EntityAttemptSmashAttackEvent(attacker.getBukkitLivingEntity(), target.getBukkitLivingEntity(), stack.asBukkitCopy(), canSmashAttack); ++ event.callEvent(); ++ final org.bukkit.event.Event.Result result = event.getResult(); ++ if (result == org.bukkit.event.Event.Result.ALLOW || (canSmashAttack && result == org.bukkit.event.Event.Result.DEFAULT)) { ++ // Paper end - Add EntityAttemptSmashAttackEvent + ServerLevel serverLevel = (ServerLevel)attacker.level(); + attacker.setDeltaMovement(attacker.getDeltaMovement().with(Direction.Axis.Y, 0.01F)); + if (attacker instanceof ServerPlayer serverPlayer) { From a3781ff3be6de0c89b667b2f03c6434b7e9b5408 Mon Sep 17 00:00:00 2001 From: Creeam <102713261+HaHaWTH@users.noreply.github.com> Date: Sun, 16 Feb 2025 11:46:37 -0800 Subject: [PATCH 120/203] Separate tick count to ensure vanilla parity (#12077) --- .../0003-Entity-Activation-Range-2.0.patch | 24 +++++------ ...ptimize-Collision-to-not-load-chunks.patch | 2 +- .../0016-Moonrise-optimisation-patches.patch | 42 +++++++++---------- ...nate-Current-redstone-implementation.patch | 2 +- ...-Incremental-chunk-and-player-saving.patch | 8 ++-- .../server/level/ServerLevel.java.patch | 10 ++++- .../minecraft/world/entity/Entity.java.patch | 9 ++-- .../craftbukkit/entity/CraftEntity.java | 3 +- 8 files changed, 54 insertions(+), 46 deletions(-) diff --git a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch index 3a408ec3d..40b1d941d 100644 --- a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch @@ -366,7 +366,7 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f import org.slf4j.Logger; diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 79d23c3403efc6dbef2381a3fa5946023f862452..3b19229427d83290bba1431bee5357e2ced34f94 100644 +index 8204528c26456929fdec0d8ba7a5a52128409097..01bc2d1639be9f04afc63e5841c5c99730ea37d8 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -377,8 +377,8 @@ index 79d23c3403efc6dbef2381a3fa5946023f862452..3b19229427d83290bba1431bee5357e2 this.entityTickList .forEach( entity -> { -@@ -979,12 +980,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - entity.tickCount++; +@@ -980,12 +981,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + entity.totalEntityAge++; // Paper - age-like counter for all entities profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()); profilerFiller.incrementCounter("tickNonPassenger"); + final boolean isActive = io.papermc.paper.entity.activation.ActivationRange.checkIfActive(entity); // Paper - EAR 2 @@ -394,7 +394,7 @@ index 79d23c3403efc6dbef2381a3fa5946023f862452..3b19229427d83290bba1431bee5357e2 } // Paper start - log detailed entity tick information } finally { -@@ -995,7 +999,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -996,7 +1000,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - log detailed entity tick information } @@ -403,7 +403,7 @@ index 79d23c3403efc6dbef2381a3fa5946023f862452..3b19229427d83290bba1431bee5357e2 if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) { passengerEntity.stopRiding(); } else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) { -@@ -1004,12 +1008,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1006,12 +1010,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString()); profilerFiller.incrementCounter("tickPassenger"); @@ -476,12 +476,12 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index bf5f2b753e3cbe3dfa8ad86df06718fbc1fbcbc4..988e5740b86c7768fee7391dc7e2900305a51be9 100644 +index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e681179343c7e75c3 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -380,6 +380,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - public boolean fixedPose = false; // Paper - Expand Pose API +@@ -381,6 +381,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private final int despawnTime; // Paper - entity despawn time limit + public int totalEntityAge; // Paper - age-like counter for all entities public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges + // Paper start - EAR 2 + public final boolean defaultActivationState; @@ -495,7 +495,7 @@ index bf5f2b753e3cbe3dfa8ad86df06718fbc1fbcbc4..988e5740b86c7768fee7391dc7e29003 public void setOrigin(@javax.annotation.Nonnull org.bukkit.Location location) { this.origin = location.toVector(); -@@ -413,6 +422,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -414,6 +423,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -509,7 +509,7 @@ index bf5f2b753e3cbe3dfa8ad86df06718fbc1fbcbc4..988e5740b86c7768fee7391dc7e29003 SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this); builder.define(DATA_SHARED_FLAGS_ID, (byte)0); builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply()); -@@ -977,6 +993,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -978,6 +994,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } else { this.wasOnFire = this.isOnFire(); if (type == MoverType.PISTON) { @@ -518,7 +518,7 @@ index bf5f2b753e3cbe3dfa8ad86df06718fbc1fbcbc4..988e5740b86c7768fee7391dc7e29003 movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -990,6 +1008,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -991,6 +1009,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } @@ -845,7 +845,7 @@ index 32f184288f6065259c921293922c1b0163df4dc4..0f346faa82b988e86834c38837f6f11b public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot // Paper start - add paper world config diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index 754cfdcd5a28287aa3545aaffdce1e391cbefc1e..1e6e940fca9d96ef410c7bf05524bd9b24db4a79 100644 +index ce880bd45fbda4829d17de8507034b3a39c68cbb..ee2f8e8deb35059824b5730a1442f383dc79f01c 100644 --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java @@ -149,6 +149,10 @@ public class PistonMovingBlockEntity extends BlockEntity { diff --git a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch index d511d3079..8739390e3 100644 --- a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch +++ b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch @@ -14,7 +14,7 @@ movement will load only the chunk the player enters anyways and avoids loading massive amounts of surrounding chunks due to large AABB lookups. diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 334859c5ff7023c730513301cc11c9837b2c7823..45f69a914d5a0565196c4105d61541047301470f 100644 +index 054ece1d539d69a4b7eec57e681179343c7e75c3..6f35067c64f378e955261e763f2bda9a0a6d0153 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -218,6 +218,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 1d2ef43ca..dbbfc7c13 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -26735,7 +26735,7 @@ index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7d if (!passengers.equals(this.lastPassengers)) { this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c639223f09 100644 +index 4a521a37e5fa0250d2cb7b4bc061d309c977e034..fc4a1efaa1f0005237340a236a231d8d3fec8d84 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -170,7 +170,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; @@ -27305,7 +27305,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 } // Paper start - log detailed entity tick information -@@ -1033,6 +1316,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1035,6 +1318,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) { @@ -27317,7 +27317,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 ServerChunkCache chunkSource = this.getChunkSource(); if (!skipSave) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit -@@ -1045,13 +1333,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1047,13 +1335,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe progress.progressStage(Component.translatable("menu.savingChunks")); } @@ -27341,7 +27341,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 // CraftBukkit start - moved from MinecraftServer.saveChunks ServerLevel worldserver1 = this; -@@ -1182,7 +1475,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1184,7 +1477,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer)entity, Entity.RemovalReason.DISCARDED); } @@ -27350,7 +27350,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 } // CraftBukkit start -@@ -1213,7 +1506,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1215,7 +1508,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -27359,7 +27359,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 } } -@@ -1224,7 +1517,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1226,7 +1519,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -27368,7 +27368,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1959,7 +2252,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1961,7 +2254,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -27377,7 +27377,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 bufferedWriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedWriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedWriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1977,13 +2270,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1979,13 +2272,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe Path path1 = path.resolve("chunks.csv"); try (Writer bufferedWriter2 = Files.newBufferedWriter(path1)) { @@ -27393,7 +27393,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 } Path path3 = path.resolve("entities.csv"); -@@ -2092,8 +2385,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2094,8 +2387,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe Locale.ROOT, "players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s", this.players.size(), @@ -27404,7 +27404,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 this.blockEntityTickers.size(), getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), -@@ -2125,15 +2418,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2127,15 +2420,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27433,7 +27433,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 } public void startTickingChunk(LevelChunk chunk) { -@@ -2151,32 +2454,45 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2153,32 +2456,45 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27486,7 +27486,7 @@ index b851520559b83c800eb240cebced0c40f1b8a66c..a293d1481b5f4a1d18addc3e518486c6 } @Override -@@ -2230,7 +2546,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2232,7 +2548,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashReportCategory = super.fillReportDetails(report); @@ -28466,7 +28466,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d } // Paper end - Share random for entities to make them more random public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason -@@ -415,6 +371,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -416,6 +372,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return this.dimensions.makeBoundingBox(x, y, z); } // Paper end @@ -28623,7 +28623,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d public Entity(EntityType entityType, Level level) { this.type = entityType; -@@ -1323,35 +1429,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1324,35 +1430,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return distance; } @@ -28725,7 +28725,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d } private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { -@@ -2658,23 +2806,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2659,23 +2807,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -28849,7 +28849,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4098,15 +4333,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4099,15 +4334,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -28875,7 +28875,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d } public int countPlayerPassengers() { -@@ -4244,77 +4481,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4245,77 +4482,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(partialTick, this.yRotO, this.yRot); } @@ -29066,7 +29066,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d public boolean touchingUnloadedChunk() { AABB aabb = this.getBoundingBox().inflate(1.0); -@@ -4467,6 +4763,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4468,6 +4764,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPosRaw(x, y, z, false); } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29082,7 +29082,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d if (!checkPosition(this, x, y, z)) { return; } -@@ -4597,6 +4902,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4598,6 +4903,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { @@ -29095,7 +29095,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit end final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers -@@ -4608,7 +4919,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4609,7 +4920,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29104,7 +29104,7 @@ index 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d this.levelCallback.onRemove(removalReason); this.onRemoval(removalReason); // Paper start - Folia schedulers -@@ -4642,7 +4953,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4643,7 +4954,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() diff --git a/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch b/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch index 64f9aa7ab..e1e8e1cdb 100644 --- a/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch +++ b/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch @@ -2337,7 +2337,7 @@ index a293d1481b5f4a1d18addc3e518486c639223f09..5bf38ab129451e867b638cfbd2d7be59 public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately -@@ -2555,6 +2556,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2557,6 +2558,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return this.chunkSource.getGenerator().getSeaLevel(); } diff --git a/paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch b/paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch index a3bfcddbc..441ccfc6b 100644 --- a/paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch +++ b/paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch @@ -50,10 +50,10 @@ index 409c1134327bfcc338c3ac5e658a83cc396645d1..cc2d442682496197d29ace79b22e6cf6 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 46dfaed12c998c219a20c711a06531aed2c68012..ebeeb63c3dca505a3ce8b88feaa5d2ca20ec24a2 100644 +index 42995dac38248032b6abecc27124adfe12ec4cab..28a67294c3e678e01d5dfd68b950234213d8e55c 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -1316,6 +1316,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1318,6 +1318,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos); } @@ -83,7 +83,7 @@ index 46dfaed12c998c219a20c711a06531aed2c68012..ebeeb63c3dca505a3ce8b88feaa5d2ca // 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 422db52e8a0a08350542670bfc9ba94ad9481d0c..1fe212e8584c177b49e83f29b1a869b534914348 100644 +index f44600604a7bf68c990cd74a1ac2d7900ff6e88e..69b8074e18775c846d5991f40bc2e0a5186500ac 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -180,6 +180,7 @@ import org.slf4j.Logger; @@ -95,7 +95,7 @@ index 422db52e8a0a08350542670bfc9ba94ad9481d0c..1fe212e8584c177b49e83f29b1a869b5 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 5e94dd9e26aa4fd6545dbaae2ae0cb51cb6f13e0..03feaf0adb8ee87e33744a4615dc2507a02f92d7 100644 +index 7d1d4abfb04829d8c4722e326c6c6b8fb2ab91f4..5a4960fdbd97d830ac79845697eea9372c48a13b 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java @@ -482,6 +482,7 @@ public abstract class PlayerList { diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index a47985fdc..b6ebadca9 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -460,7 +460,7 @@ } public void resetEmptyTime() { -@@ -746,18 +_,45 @@ +@@ -746,18 +_,46 @@ } } @@ -487,6 +487,7 @@ entity.setOldPosAndRot(); ProfilerFiller profilerFiller = Profiler.get(); entity.tickCount++; ++ entity.totalEntityAge++; // Paper - age-like counter for all entities profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()); profilerFiller.incrementCounter("tickNonPassenger"); entity.tick(); @@ -506,7 +507,12 @@ } private void tickPassenger(Entity ridingEntity, Entity passengerEntity) { -@@ -770,6 +_,7 @@ +@@ -766,10 +_,12 @@ + } else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) { + passengerEntity.setOldPosAndRot(); + passengerEntity.tickCount++; ++ passengerEntity.totalEntityAge++; // Paper - age-like counter for all entities + ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString()); profilerFiller.incrementCounter("tickPassenger"); passengerEntity.rideTick(); 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 9340b5b32..2ca8aeca6 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 @@ -127,7 +127,7 @@ private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0}; private long pistonDeltasGameTime; private EntityDimensions dimensions; -@@ -250,6 +_,59 @@ +@@ -250,6 +_,60 @@ private final List movementThisTick = new ArrayList<>(); private final Set blocksInside = new ReferenceArraySet<>(); private final LongSet visitedBlocks = new LongOpenHashSet(); @@ -158,6 +158,7 @@ + public boolean freezeLocked = false; // Paper - Freeze Tick Lock API + public boolean fixedPose = false; // Paper - Expand Pose API + private final int despawnTime; // Paper - entity despawn time limit ++ public int totalEntityAge; // Paper - age-like counter for all entities + public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges + + public void setOrigin(@javax.annotation.Nonnull org.bukkit.Location location) { @@ -369,7 +370,7 @@ public void tick() { + // Paper start - entity despawn time limit -+ if (this.despawnTime >= 0 && this.tickCount >= this.despawnTime) { ++ if (this.despawnTime >= 0 && this.totalEntityAge >= this.despawnTime) { + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); + return; + } @@ -798,7 +799,7 @@ + if (this.maxAirTicks != this.getDefaultMaxAirSupply()) { + compound.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply()); + } -+ compound.putInt("Spigot.ticksLived", this.tickCount); ++ compound.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper + // CraftBukkit end Component customName = this.getCustomName(); if (customName != null) { @@ -860,7 +861,7 @@ + // CraftBukkit start + // Spigot start + if (this instanceof net.minecraft.world.entity.LivingEntity) { -+ this.tickCount = compound.getInt("Spigot.ticksLived"); ++ this.totalEntityAge = compound.getInt("Spigot.ticksLived"); // Paper + } + // Spigot end + this.persist = !compound.contains("Bukkit.persist") || compound.getBoolean("Bukkit.persist"); 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 f8762064e..1ee0ad266 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 @@ -519,13 +519,14 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public int getTicksLived() { - return this.getHandle().tickCount; + return this.getHandle().totalEntityAge; } @Override public void setTicksLived(int value) { Preconditions.checkArgument(value > 0, "Age value (%s) must be greater than 0", value); this.getHandle().tickCount = value; + this.getHandle().totalEntityAge = value; } public Entity getHandle() { From 2a4a115432f5a1d78399a1784ae0c2e9531281e3 Mon Sep 17 00:00:00 2001 From: TonytheMacaroni Date: Sun, 16 Feb 2025 14:46:59 -0500 Subject: [PATCH 121/203] Add EntityEquipmentChangedEvent (#12011) --- .../event/player/PlayerArmorChangeEvent.java | 23 +++++ .../entity/EntityEquipmentChangedEvent.java | 89 +++++++++++++++++++ .../world/entity/LivingEntity.java.patch | 47 ++++++++-- 3 files changed, 154 insertions(+), 5 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/entity/EntityEquipmentChangedEvent.java diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java index c7cc612ec..f146a8cc9 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java @@ -5,6 +5,7 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -16,8 +17,10 @@ import static org.bukkit.Material.*; * Called when the player themselves change their armor items *

* Not currently called for environmental factors though it MAY BE IN THE FUTURE + * @apiNote Use {@link io.papermc.paper.event.entity.EntityEquipmentChangedEvent} for all entity equipment changes */ @NullMarked +@ApiStatus.Obsolete(since = "1.21.4") public class PlayerArmorChangeEvent extends PlayerEvent { private static final HandlerList HANDLER_LIST = new HandlerList(); @@ -38,11 +41,27 @@ public class PlayerArmorChangeEvent extends PlayerEvent { * Gets the type of slot being altered. * * @return type of slot being altered + * @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot. Use {@link #getSlot()} instead. */ + @Deprecated(since = "1.21.4") public SlotType getSlotType() { return this.slotType; } + /** + * Gets the slot being altered. + * + * @return slot being altered + */ + public EquipmentSlot getSlot() { + return switch (this.slotType) { + case HEAD -> EquipmentSlot.HEAD; + case CHEST -> EquipmentSlot.CHEST; + case LEGS -> EquipmentSlot.LEGS; + case FEET -> EquipmentSlot.FEET; + }; + } + /** * Gets the existing item that's being replaced * @@ -70,6 +89,10 @@ public class PlayerArmorChangeEvent extends PlayerEvent { return HANDLER_LIST; } + /** + * @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot. + */ + @Deprecated(since = "1.21.4") public enum SlotType { HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET, DRAGON_HEAD, PIGLIN_HEAD), CHEST(NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA), diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/EntityEquipmentChangedEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityEquipmentChangedEvent.java new file mode 100644 index 000000000..ebb31c12d --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/EntityEquipmentChangedEvent.java @@ -0,0 +1,89 @@ +package io.papermc.paper.event.entity; + +import java.util.Collections; +import java.util.Map; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; + +/** + * Called whenever a change to an entity's equipment has been detected. This event is called after effects from + * attribute modifiers and enchantments have been updated. + *

+ * Examples of actions that can trigger this event: + *

    + *
  • An entity being added to a world.
  • + *
  • A player logging in.
  • + *
  • The durability of an equipment item changing.
  • + *
  • A dispenser equipping an item onto an entity.
  • + *
  • An entity picking up an armor or weapon item from the ground.
  • + *
  • A player changing their equipped armor.
  • + *
  • A player changes their currently held item.
  • + *
+ */ +@NullMarked +public class EntityEquipmentChangedEvent extends EntityEvent { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final Map equipmentChanges; + + @ApiStatus.Internal + public EntityEquipmentChangedEvent(final LivingEntity entity, final Map equipmentChanges) { + super(entity); + + this.equipmentChanges = equipmentChanges; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) this.entity; + } + + /** + * Gets a map of changed slots to their respective equipment changes. + * + * @return the equipment changes map + */ + public @Unmodifiable Map getEquipmentChanges() { + return Collections.unmodifiableMap(this.equipmentChanges); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + /** + * Represents a change in equipment for a single equipment slot. + */ + @ApiStatus.NonExtendable + public interface EquipmentChange { + + /** + * Gets the existing item that is being replaced. + * + * @return the existing item + */ + @Contract(pure = true, value = "-> new") + ItemStack oldItem(); + + /** + * Gets the new item that is replacing the existing item. + * + * @return the new item + */ + @Contract(pure = true, value = "-> new") + ItemStack newItem(); + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index 8015fbab2..862afaa4e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -1336,20 +1336,57 @@ Map map = this.collectEquipmentChanges(); if (map != null) { this.handleHandSwap(map); -@@ -2595,6 +_,13 @@ +@@ -2586,6 +_,20 @@ + @Nullable + private Map collectEquipmentChanges() { + Map map = null; ++ // Paper start - EntityEquipmentChangedEvent ++ record EquipmentChangeImpl(org.bukkit.inventory.ItemStack oldItem, org.bukkit.inventory.ItemStack newItem) implements io.papermc.paper.event.entity.EntityEquipmentChangedEvent.EquipmentChange { ++ @Override ++ public org.bukkit.inventory.ItemStack oldItem() { ++ return this.oldItem.clone(); ++ } ++ ++ @Override ++ public org.bukkit.inventory.ItemStack newItem() { ++ return this.newItem.clone(); ++ } ++ } ++ Map equipmentChanges = null; ++ // Paper end - EntityEquipmentChangedEvent + + for (EquipmentSlot equipmentSlot : EquipmentSlot.VALUES) { + ItemStack itemStack = switch (equipmentSlot.getType()) { +@@ -2595,11 +_,20 @@ }; ItemStack itemBySlot = this.getItemBySlot(equipmentSlot); if (this.equipmentHasChanged(itemStack, itemBySlot)) { -+ // Paper start - PlayerArmorChangeEvent ++ // Paper start - EntityEquipmentChangedEvent, PlayerArmorChangeEvent ++ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemStack); ++ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemBySlot); + if (this instanceof ServerPlayer && equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) { -+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemStack); -+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemBySlot); + new com.destroystokyo.paper.event.player.PlayerArmorChangeEvent((org.bukkit.entity.Player) this.getBukkitEntity(), com.destroystokyo.paper.event.player.PlayerArmorChangeEvent.SlotType.valueOf(equipmentSlot.name()), oldItem, newItem).callEvent(); + } -+ // Paper end - PlayerArmorChangeEvent ++ // Paper end - EntityEquipmentChangedEvent, PlayerArmorChangeEvent if (map == null) { map = Maps.newEnumMap(EquipmentSlot.class); ++ equipmentChanges = Maps.newEnumMap(org.bukkit.inventory.EquipmentSlot.class); // Paper - EntityEquipmentChangedEvent } + + map.put(equipmentSlot, itemBySlot); ++ equipmentChanges.put(org.bukkit.craftbukkit.CraftEquipmentSlot.getSlot(equipmentSlot), new EquipmentChangeImpl(oldItem, newItem)); // Paper - EntityEquipmentChangedEvent + AttributeMap attributes = this.getAttributes(); + if (!itemStack.isEmpty()) { + this.stopLocationBasedEffects(itemStack, equipmentSlot, attributes); +@@ -2624,6 +_,8 @@ + } + } + } ++ ++ new io.papermc.paper.event.entity.EntityEquipmentChangedEvent(this.getBukkitLivingEntity(), equipmentChanges).callEvent(); // Paper - EntityEquipmentChangedEvent + } + + return map; @@ -2664,7 +_,7 @@ this.lastBodyItemStack = itemStack; } From 06f96dd655bba701caeee26433bad972c577a04f Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:10:45 -0300 Subject: [PATCH 122/203] Improvement in /plugins command (#12121) --- .../paper/command/PaperPluginsCommand.java | 137 +++++++++--------- 1 file changed, 70 insertions(+), 67 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java b/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java index f0fce4113..c4b2a8bf9 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java @@ -11,6 +11,11 @@ import io.papermc.paper.plugin.provider.ProviderStatus; import io.papermc.paper.plugin.provider.ProviderStatusHolder; import io.papermc.paper.plugin.provider.type.paper.PaperPluginParent; import io.papermc.paper.plugin.provider.type.spigot.SpigotPluginProvider; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.TreeMap; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.JoinConfiguration; import net.kyori.adventure.text.TextComponent; @@ -23,51 +28,38 @@ import org.bukkit.command.defaults.BukkitCommand; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.TreeMap; +import org.jspecify.annotations.NullMarked; +@NullMarked public class PaperPluginsCommand extends BukkitCommand { private static final TextColor INFO_COLOR = TextColor.color(52, 159, 218); - // TODO: LINK? private static final Component SERVER_PLUGIN_INFO = Component.text("ℹ What is a server plugin?", INFO_COLOR) .append(asPlainComponents(""" - Server plugins can add new behavior to your server! - You can find new plugins on Paper's plugin repository, Hangar. - - - """)); - - private static final Component SERVER_INITIALIZER_INFO = Component.text("ℹ What is a server initializer?", INFO_COLOR) - .append(asPlainComponents(""" - Server initializers are ran before your server - starts and are provided by paper plugins. - """)); + Server plugins can add new behavior to your server! + You can find new plugins on Paper's plugin repository, Hangar. + + https://hangar.papermc.io/ + """)); private static final Component LEGACY_PLUGIN_INFO = Component.text("ℹ What is a legacy plugin?", INFO_COLOR) .append(asPlainComponents(""" - A legacy plugin is a plugin that was made on - very old unsupported versions of the game. - - It is encouraged that you replace this plugin, - as they might not work in the future and may cause - performance issues. - """)); + A legacy plugin is a plugin that was made on + very old unsupported versions of the game. + + It is encouraged that you replace this plugin, + as they might not work in the future and may cause + performance issues. + """)); private static final Component LEGACY_PLUGIN_STAR = Component.text('*', TextColor.color(255, 212, 42)).hoverEvent(LEGACY_PLUGIN_INFO); private static final Component INFO_ICON_START = Component.text("ℹ ", INFO_COLOR); - private static final Component PAPER_HEADER = Component.text("Paper Plugins:", TextColor.color(2, 136, 209)); - private static final Component BUKKIT_HEADER = Component.text("Bukkit Plugins:", TextColor.color(237, 129, 6)); private static final Component PLUGIN_TICK = Component.text("- ", NamedTextColor.DARK_GRAY); private static final Component PLUGIN_TICK_EMPTY = Component.text(" "); + private static final Component INFO_ICON_SERVER_PLUGIN = INFO_ICON_START.hoverEvent(SERVER_PLUGIN_INFO).clickEvent(ClickEvent.openUrl("https://docs.papermc.io/paper/adding-plugins")); + private static final Type JAVA_PLUGIN_PROVIDER_TYPE = new TypeToken>() {}.getType(); public PaperPluginsCommand() { @@ -75,17 +67,17 @@ public class PaperPluginsCommand extends BukkitCommand { this.description = "Gets a list of plugins running on the server"; this.usageMessage = "/plugins"; this.setPermission("bukkit.command.plugins"); - this.setAliases(Arrays.asList("pl")); + this.setAliases(List.of("pl")); } - private static List formatProviders(TreeMap> plugins) { - List components = new ArrayList<>(plugins.size()); - for (PluginProvider entry : plugins.values()) { + private static List formatProviders(final TreeMap> plugins) { + final List components = new ArrayList<>(plugins.size()); + for (final PluginProvider entry : plugins.values()) { components.add(formatProvider(entry)); } boolean isFirst = true; - List formattedSublists = new ArrayList<>(); + final List formattedSubLists = new ArrayList<>(); /* Split up the plugin list for each 10 plugins to get size down @@ -93,30 +85,29 @@ public class PaperPluginsCommand extends BukkitCommand { - Plugin 1, Plugin 2, .... Plugin 10, Plugin 11, Plugin 12 ... Plugin 20, */ - for (List componentSublist : Lists.partition(components, 10)) { + for (final List componentSublist : Lists.partition(components, 10)) { Component component = Component.space(); if (isFirst) { component = component.append(PLUGIN_TICK); isFirst = false; } else { component = PLUGIN_TICK_EMPTY; - //formattedSublists.add(Component.empty()); // Add an empty line, the auto chat wrapping and this makes it quite jarring. } - formattedSublists.add(component.append(Component.join(JoinConfiguration.commas(true), componentSublist))); + formattedSubLists.add(component.append(Component.join(JoinConfiguration.commas(true), componentSublist))); } - return formattedSublists; + return formattedSubLists; } - private static Component formatProvider(PluginProvider provider) { - TextComponent.Builder builder = Component.text(); - if (provider instanceof SpigotPluginProvider spigotPluginProvider && CraftMagicNumbers.isLegacy(spigotPluginProvider.getMeta())) { + private static Component formatProvider(final PluginProvider provider) { + final TextComponent.Builder builder = Component.text(); + if (provider instanceof final SpigotPluginProvider spigotPluginProvider && CraftMagicNumbers.isLegacy(spigotPluginProvider.getMeta())) { builder.append(LEGACY_PLUGIN_STAR); } - String name = provider.getMeta().getName(); - Component pluginName = Component.text(name, fromStatus(provider)) + final String name = provider.getMeta().getName(); + final Component pluginName = Component.text(name, fromStatus(provider)) .clickEvent(ClickEvent.runCommand("/version " + name)); builder.append(pluginName); @@ -124,9 +115,20 @@ public class PaperPluginsCommand extends BukkitCommand { return builder.build(); } - private static Component asPlainComponents(String strings) { - net.kyori.adventure.text.TextComponent.Builder builder = Component.text(); - for (String string : strings.split("\n")) { + private static Component header(final String header, final int color, final int count, final boolean showSize) { + final TextComponent.Builder componentHeader = Component.text().color(TextColor.color(color)) + .append(Component.text(header)); + + if (showSize) { + componentHeader.appendSpace().append(Component.text("(" + count + ")")); + } + + return componentHeader.append(Component.text(":")).build(); + } + + private static Component asPlainComponents(final String strings) { + final net.kyori.adventure.text.TextComponent.Builder builder = Component.text(); + for (final String string : strings.split("\n")) { builder.append(Component.newline()); builder.append(Component.text(string, NamedTextColor.WHITE)); } @@ -134,13 +136,13 @@ public class PaperPluginsCommand extends BukkitCommand { return builder.build(); } - private static TextColor fromStatus(PluginProvider provider) { - if (provider instanceof ProviderStatusHolder statusHolder && statusHolder.getLastProvidedStatus() != null) { - ProviderStatus status = statusHolder.getLastProvidedStatus(); + private static TextColor fromStatus(final PluginProvider provider) { + if (provider instanceof final ProviderStatusHolder statusHolder && statusHolder.getLastProvidedStatus() != null) { + final ProviderStatus status = statusHolder.getLastProvidedStatus(); // Handle enabled/disabled game plugins if (status == ProviderStatus.INITIALIZED && GenericTypeReflector.isSuperType(JAVA_PLUGIN_PROVIDER_TYPE, provider.getClass())) { - Plugin plugin = Bukkit.getPluginManager().getPlugin(provider.getMeta().getName()); + final Plugin plugin = Bukkit.getPluginManager().getPlugin(provider.getMeta().getName()); // Plugin doesn't exist? Could be due to it being removed. if (plugin == null) { return NamedTextColor.RED; @@ -153,7 +155,7 @@ public class PaperPluginsCommand extends BukkitCommand { case INITIALIZED -> NamedTextColor.GREEN; case ERRORED -> NamedTextColor.RED; }; - } else if (provider instanceof PaperPluginParent.PaperServerPluginProvider serverPluginProvider && serverPluginProvider.shouldSkipCreation()) { + } else if (provider instanceof final PaperPluginParent.PaperServerPluginProvider serverPluginProvider && serverPluginProvider.shouldSkipCreation()) { // Paper plugins will be skipped if their provider is skipped due to their initializer failing. // Show them as red return NamedTextColor.RED; @@ -165,15 +167,14 @@ public class PaperPluginsCommand extends BukkitCommand { } @Override - public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) { + public boolean execute(final CommandSender sender, final String currentAlias, final String[] args) { if (!this.testPermission(sender)) return true; - TreeMap> paperPlugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - TreeMap> spigotPlugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + final TreeMap> paperPlugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + final TreeMap> spigotPlugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); - - for (PluginProvider provider : LaunchEntryPointHandler.INSTANCE.get(Entrypoint.PLUGIN).getRegisteredProviders()) { - PluginMeta configuration = provider.getMeta(); + for (final PluginProvider provider : LaunchEntryPointHandler.INSTANCE.get(Entrypoint.PLUGIN).getRegisteredProviders()) { + final PluginMeta configuration = provider.getMeta(); if (provider instanceof SpigotPluginProvider) { spigotPlugins.put(configuration.getDisplayName(), provider); @@ -182,34 +183,36 @@ public class PaperPluginsCommand extends BukkitCommand { } } - Component infoMessage = Component.text("Server Plugins (%s):".formatted(paperPlugins.size() + spigotPlugins.size()), NamedTextColor.WHITE); - //.append(INFO_ICON_START.hoverEvent(SERVER_PLUGIN_INFO)); TODO: Add docs + final int sizePaperPlugins = paperPlugins.size(); + final int sizeSpigotPlugins = spigotPlugins.size(); + final int sizePlugins = sizePaperPlugins + sizeSpigotPlugins; + final boolean hasAllPluginTypes = (sizePaperPlugins > 0 && sizeSpigotPlugins > 0); + + final Component infoMessage = Component.text().append(INFO_ICON_SERVER_PLUGIN).append(Component.text("Server Plugins (%s):".formatted(sizePlugins), NamedTextColor.WHITE)).build(); sender.sendMessage(infoMessage); if (!paperPlugins.isEmpty()) { - sender.sendMessage(PAPER_HEADER); + sender.sendMessage(header("Paper Plugins", 0x0288D1, sizePaperPlugins, hasAllPluginTypes)); } - for (Component component : formatProviders(paperPlugins)) { + for (final Component component : formatProviders(paperPlugins)) { sender.sendMessage(component); } if (!spigotPlugins.isEmpty()) { - sender.sendMessage(BUKKIT_HEADER); + sender.sendMessage(header("Bukkit Plugins", 0xED8106, sizePaperPlugins, hasAllPluginTypes)); } - - for (Component component : formatProviders(spigotPlugins)) { + + for (final Component component : formatProviders(spigotPlugins)) { sender.sendMessage(component); } return true; } - @NotNull @Override - public List tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException { + public List tabComplete(final CommandSender sender, final String alias, final String[] args) throws IllegalArgumentException { return Collections.emptyList(); } - } From 28d07dc5ab5e96c1a471bc37b613d158c5c7f197 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 16 Feb 2025 12:18:29 -0800 Subject: [PATCH 123/203] use correct spigot plugin count --- .../main/java/io/papermc/paper/command/PaperPluginsCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java b/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java index c4b2a8bf9..41c95f00b 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/PaperPluginsCommand.java @@ -201,7 +201,7 @@ public class PaperPluginsCommand extends BukkitCommand { } if (!spigotPlugins.isEmpty()) { - sender.sendMessage(header("Bukkit Plugins", 0xED8106, sizePaperPlugins, hasAllPluginTypes)); + sender.sendMessage(header("Bukkit Plugins", 0xED8106, sizeSpigotPlugins, hasAllPluginTypes)); } for (final Component component : formatProviders(spigotPlugins)) { From 60394c5b985322ba7a3f8ab626a290f4cb8bb67c Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sun, 16 Feb 2025 21:44:08 +0100 Subject: [PATCH 124/203] Fix PlayerReadyArrowEvent cancellation desync (#12111) --- .../world/entity/player/Player.java.patch | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch index dd2387ae9..597b6bda1 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -645,18 +645,21 @@ } @Override -@@ -1988,17 +_,28 @@ +@@ -1988,17 +_,32 @@ return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING); } + // Paper start - PlayerReadyArrowEvent -+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) { -+ return !(this instanceof ServerPlayer) || -+ new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent( -+ ((ServerPlayer) this).getBukkitEntity(), -+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow), -+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack) -+ ).callEvent(); ++ // We pass a result mutable boolean in to allow the caller of this method to know if the event was cancelled. ++ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack, final org.apache.commons.lang3.mutable.MutableBoolean cancelled) { ++ if (!(this instanceof final ServerPlayer serverPlayer)) return true; ++ final boolean notCancelled = new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent( ++ serverPlayer.getBukkitEntity(), ++ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow), ++ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack) ++ ).callEvent(); ++ if (!notCancelled) cancelled.setValue(true); ++ return notCancelled; + } + // Paper end - PlayerReadyArrowEvent + @@ -666,16 +669,25 @@ return ItemStack.EMPTY; } else { - Predicate supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles(); -+ Predicate supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles().and(item -> this.tryReadyArrow(shootable, item)); // Paper - PlayerReadyArrowEvent ++ final org.apache.commons.lang3.mutable.MutableBoolean anyEventCancelled = new org.apache.commons.lang3.mutable.MutableBoolean(); // Paper - PlayerReadyArrowEvent ++ Predicate supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles().and(item -> this.tryReadyArrow(shootable, item, anyEventCancelled)); // Paper - PlayerReadyArrowEvent ItemStack heldProjectile = ProjectileWeaponItem.getHeldProjectile(this, supportedHeldProjectiles); if (!heldProjectile.isEmpty()) { return heldProjectile; } else { - supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles(); -+ supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles().and(item -> this.tryReadyArrow(shootable, item)); // Paper - PlayerReadyArrowEvent ++ supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles().and(item -> this.tryReadyArrow(shootable, item, anyEventCancelled)); // Paper - PlayerReadyArrowEvent for (int i = 0; i < this.inventory.getContainerSize(); i++) { ItemStack item = this.inventory.getItem(i); +@@ -2007,6 +_,7 @@ + } + } + ++ if (anyEventCancelled.booleanValue() && !this.abilities.instabuild && this instanceof final ServerPlayer player) this.resyncUsingItem(player); // Paper - resync if no item matched the Predicate + return this.abilities.instabuild ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; + } + } @@ -2089,12 +_,20 @@ } From b27e11cce6c0dcc22804d5d0b652b7c25ebe2940 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 16 Feb 2025 22:04:15 +0100 Subject: [PATCH 125/203] Fix bad world to chunk coordinate example in javadocs (#12131) --- paper-api/src/main/java/org/bukkit/World.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index 987a98074..015d852d5 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -1123,8 +1123,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * on the main Server Thread. * * @deprecated Use either the Future or the Consumer based methods - * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @param cb Callback to receive the chunk when it is loaded. * will be executed synchronously */ @@ -1192,8 +1192,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * The {@link java.util.function.Consumer} will always be executed synchronously * on the main Server Thread. * - * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @param cb Callback to receive the chunk when it is loaded. * will be executed synchronously */ @@ -1214,8 +1214,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * The {@link java.util.function.Consumer} will always be executed synchronously * on the main Server Thread. * - * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @param gen Should we generate a chunk if it doesn't exist or not * @param cb Callback to receive the chunk when it is loaded. * will be executed synchronously @@ -1237,8 +1237,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * The {@link java.util.function.Consumer} will always be executed synchronously * on the main Server Thread. * - * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @param gen Should we generate a chunk if it doesn't exist or not * @param urgent If true, the chunk may be prioritised to be loaded above other chunks in queue * @param cb Callback to receive the chunk when it is loaded. @@ -1260,10 +1260,10 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * The {@link Runnable} will always be executed synchronously * on the main Server Thread, and when invoked all chunks requested will be loaded. * - * @param minX Minimum chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param minZ Minimum chunk Z-coordinate of the chunk - floor(world coordinate / 16) - * @param maxX Maximum chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param maxZ Maximum chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param minX Minimum Chunk x-coordinate + * @param minZ Minimum Chunk z-coordinate + * @param maxX Maximum Chunk x-coordinate + * @param maxZ Maximum Chunk z-coordinate * @param urgent If true, the chunks may be prioritised to be loaded above other chunks in queue * @param cb Callback to invoke when all chunks are loaded. * Will be executed synchronously @@ -1449,8 +1449,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * The future will always be executed synchronously * on the main Server Thread. * - * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @return Future that will resolve when the chunk is loaded */ default @NotNull java.util.concurrent.CompletableFuture getChunkAtAsync(final int x, final int z) { @@ -1470,8 +1470,8 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * The future will always be executed synchronously * on the main Server Thread. * - * @param x Chunk X-coordinate of the chunk - floor(world coordinate / 16) - * @param z Chunk Z-coordinate of the chunk - floor(world coordinate / 16) + * @param x Chunk x-coordinate + * @param z Chunk z-coordinate * @param gen Should we generate a chunk if it doesn't exist or not * @return Future that will resolve when the chunk is loaded */ From 88cdd22076758fae1fd0e6e7780ca887e4d8c082 Mon Sep 17 00:00:00 2001 From: FlorianMichael Date: Sun, 16 Feb 2025 22:06:01 +0100 Subject: [PATCH 126/203] Fixup luck and random implementation in CB loot-tables (#11926) --- .../level/storage/loot/LootTable.java.patch | 7 ++++--- .../org/bukkit/craftbukkit/CraftLootTable.java | 16 +++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch index 21a8108d1..53f28e336 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -24,13 +24,14 @@ } public void fill(Container container, LootParams params, long seed) { +- LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); + // CraftBukkit start -+ this.fillInventory(container, params, seed, false); ++ this.fill(container, params, seed == 0L ? null : RandomSource.create(seed), false); + } + -+ public void fillInventory(Container container, LootParams params, long seed, boolean plugin) { ++ public void fill(Container container, LootParams params, RandomSource randomSource, boolean plugin) { + // CraftBukkit end - LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSeed(seed).create(this.randomSequence); ++ LootContext lootContext = new LootContext.Builder(params).withOptionalRandomSource(randomSource).create(this.randomSequence); ObjectArrayList randomItems = this.getRandomItems(lootContext); RandomSource random = lootContext.getRandom(); + // CraftBukkit start diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java index 5fd22a80e..4f29e9af0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftLootTable.java @@ -27,6 +27,7 @@ import org.bukkit.craftbukkit.inventory.CraftInventory; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.util.RandomSourceWrapper; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.loot.LootContext; @@ -68,8 +69,8 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { @Override public Collection populateLoot(Random random, LootContext context) { Preconditions.checkArgument(context != null, "LootContext cannot be null"); - LootParams nmsContext = this.convertContext(context, random); - List nmsItems = this.handle.getRandomItems(nmsContext); + LootParams nmsContext = this.convertContext(context); + List nmsItems = this.handle.getRandomItems(nmsContext, random == null ? null : new RandomSourceWrapper(random)); Collection bukkit = new ArrayList<>(nmsItems.size()); for (net.minecraft.world.item.ItemStack item : nmsItems) { @@ -86,12 +87,12 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { public void fillInventory(Inventory inventory, Random random, LootContext context) { Preconditions.checkArgument(inventory != null, "Inventory cannot be null"); Preconditions.checkArgument(context != null, "LootContext cannot be null"); - LootParams nmsContext = this.convertContext(context, random); + LootParams nmsContext = this.convertContext(context); CraftInventory craftInventory = (CraftInventory) inventory; Container handle = craftInventory.getInventory(); // TODO: When events are added, call event here w/ custom reason? - this.getHandle().fillInventory(handle, nmsContext, random.nextLong(), true); + this.getHandle().fill(handle, nmsContext, random == null ? null : new RandomSourceWrapper(random), true); } @Override @@ -99,19 +100,16 @@ public class CraftLootTable implements org.bukkit.loot.LootTable { return this.key; } - private LootParams convertContext(LootContext context, Random random) { + private LootParams convertContext(LootContext context) { Preconditions.checkArgument(context != null, "LootContext cannot be null"); Location loc = context.getLocation(); Preconditions.checkArgument(loc.getWorld() != null, "LootContext.getLocation#getWorld cannot be null"); ServerLevel handle = ((CraftWorld) loc.getWorld()).getHandle(); LootParams.Builder builder = new LootParams.Builder(handle); - if (random != null) { - // builder = builder.withRandom(new RandomSourceWrapper(random)); - } this.setMaybe(builder, LootContextParams.ORIGIN, CraftLocation.toVec3D(loc)); if (this.getHandle() != LootTable.EMPTY) { - // builder.luck(context.getLuck()); + builder.withLuck(context.getLuck()); if (context.getLootedEntity() != null) { Entity nmsLootedEntity = ((CraftEntity) context.getLootedEntity()).getHandle(); From 84609dc046f33fb756362909633db7fcd90d0609 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sun, 16 Feb 2025 13:55:27 -0800 Subject: [PATCH 127/203] Don't auto-create any brig redirects (#11954) --- .../brigadier/CommandRegistrationFlag.java | 5 ++ .../paper/command/brigadier/Commands.java | 5 ++ .../brigadier/tree/CommandNode.java.patch | 3 +- .../minecraft/commands/Commands.java.patch | 78 ++++--------------- .../command/brigadier/ApiMirrorRootNode.java | 4 +- .../command/brigadier/PaperBrigadier.java | 31 +++++--- .../command/brigadier/PaperCommands.java | 59 +++++--------- .../command/brigadier/PluginCommandMeta.java | 26 +++++++ .../command/brigadier/PluginCommandNode.java | 50 ------------ 9 files changed, 95 insertions(+), 166 deletions(-) create mode 100644 paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandMeta.java delete mode 100644 paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandNode.java 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 7e24babf7..7e1d500b1 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 @@ -10,5 +10,10 @@ import org.jetbrains.annotations.ApiStatus; */ @ApiStatus.Internal public enum CommandRegistrationFlag { + + /** + * @deprecated This is the default behavior now. + */ + @Deprecated(since = "1.21.4") FLATTEN_ALIASES } diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/Commands.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/Commands.java index e32559772..866442924 100644 --- a/paper-api/src/main/java/io/papermc/paper/command/brigadier/Commands.java +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/Commands.java @@ -113,6 +113,7 @@ public interface Commands extends Registrar { *

Commands have certain overriding behavior: *

    *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • *
  • The main command/namespaced label will override already existing commands
  • *
* @@ -129,6 +130,7 @@ public interface Commands extends Registrar { *

Commands have certain overriding behavior: *

    *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • *
  • The main command/namespaced label will override already existing commands
  • *
* @@ -146,6 +148,7 @@ public interface Commands extends Registrar { *

Commands have certain overriding behavior: *

    *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • *
  • The main command/namespaced label will override already existing commands
  • *
* @@ -163,6 +166,7 @@ public interface Commands extends Registrar { *

Commands have certain overriding behavior: *

    *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • *
  • The main command/namespaced label will override already existing commands
  • *
* @@ -179,6 +183,7 @@ public interface Commands extends Registrar { *

Commands have certain overriding behavior: *

    *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • *
  • The main command/namespaced label will override already existing commands
  • *
* 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 bb97c0d52..f892ceeba 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 @@ -1,6 +1,6 @@ --- a/com/mojang/brigadier/tree/CommandNode.java +++ b/com/mojang/brigadier/tree/CommandNode.java -@@ -27,11 +_,21 @@ +@@ -27,11 +_,22 @@ private final Map> children = new LinkedHashMap<>(); private final Map> literals = new LinkedHashMap<>(); private final Map> arguments = new LinkedHashMap<>(); @@ -13,6 +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 + // 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 0c4203d03..b5fdc04cc 100644 --- a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -251,6 +_,30 @@ +@@ -251,6 +_,24 @@ PublishCommand.register(this.dispatcher); } @@ -14,17 +14,11 @@ + // Paper start - Brigadier Command API + // Create legacy minecraft namespace commands + for (final CommandNode node : new java.util.ArrayList<>(this.dispatcher.getRoot().getChildren())) { -+ // The brigadier dispatcher is not able to resolve nested redirects. -+ // E.g. registering the alias minecraft:tp cannot redirect to tp, as tp itself redirects to teleport. -+ // Instead, target the first none redirecting node. -+ CommandNode flattenedAliasTarget = node; -+ while (flattenedAliasTarget.getRedirect() != null) flattenedAliasTarget = flattenedAliasTarget.getRedirect(); -+ -+ this.dispatcher.register( -+ com.mojang.brigadier.builder.LiteralArgumentBuilder.literal("minecraft:" + node.getName()) -+ .executes(flattenedAliasTarget.getCommand()) -+ .requires(flattenedAliasTarget.getRequirement()) -+ .redirect(flattenedAliasTarget) ++ this.dispatcher.getRoot().addChild( ++ io.papermc.paper.command.brigadier.PaperBrigadier.copyLiteral( ++ "minecraft:" + node.getName(), ++ (com.mojang.brigadier.tree.LiteralCommandNode) node ++ ) + ); + } + // Paper end - Brigadier Command API @@ -150,11 +144,10 @@ } return null; -@@ -360,25 +_,130 @@ +@@ -360,26 +_,85 @@ } public void sendCommands(ServerPlayer player) { -- Map, CommandNode> map = Maps.newHashMap(); + // Paper start - Send empty commands if tab completion is disabled + if (org.spigotmc.SpigotConfig.tabComplete < 0) { + player.connection.send(new ClientboundCommandsPacket(new RootCommandNode<>())); @@ -182,7 +175,7 @@ + + private void sendAsync(ServerPlayer player, java.util.Collection> dispatcherRootChildren) { + // Paper end - Perf: Async command map building -+ Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues + Map, CommandNode> map = Maps.newHashMap(); RootCommandNode rootCommandNode = new RootCommandNode<>(); map.put(this.dispatcher.getRoot(), rootCommandNode); - this.fillUsableCommands(this.dispatcher.getRoot(), rootCommandNode, player.createCommandSourceStack(), map); @@ -224,7 +217,6 @@ Map, CommandNode> commandNodeToSuggestionNode ) { - for (CommandNode commandNode : rootCommandSource.getChildren()) { -+ commandNodeToSuggestionNode.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains(":")); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below + for (CommandNode commandNode : children) { // Paper - Perf: Async command map building; pass copy of children + // Paper start - Brigadier API + if (commandNode.clientNode != null) { @@ -234,58 +226,16 @@ + if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot if (commandNode.canUse(source)) { ArgumentBuilder argumentBuilder = (ArgumentBuilder) commandNode.createBuilder(); -+ // Paper start -+ /* -+ Because of how commands can be yeeted right left and center due to bad bukkit practices -+ we need to be able to ensure that ALL commands are registered (even redirects). -+ -+ What this will do is IF the redirect seems to be "dead" it will create a builder and essentially populate (flatten) -+ all the children from the dead redirect to the node. -+ -+ So, if minecraft:msg redirects to msg but the original msg node has been overriden minecraft:msg will now act as msg and will explicilty inherit its children. -+ -+ The only way to fix this is to either: -+ - Send EVERYTHING flattened, don't use redirects -+ - Don't allow command nodes to be deleted -+ - Do this :) -+ */ -+ -+ // Is there an invalid command redirect? -+ if (argumentBuilder.getRedirect() != null && commandNodeToSuggestionNode.get(argumentBuilder.getRedirect()) == null) { -+ // Create the argument builder with the same values as the specified node, but with a different literal and populated children -+ -+ CommandNode redirect = argumentBuilder.getRedirect(); -+ // Diff copied from LiteralCommand#createBuilder -+ final com.mojang.brigadier.builder.LiteralArgumentBuilder builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName()); -+ builder.requires(redirect.getRequirement()); -+ // builder.forward(redirect.getRedirect(), redirect.getRedirectModifier(), redirect.isFork()); We don't want to migrate the forward, since it's invalid. -+ if (redirect.getCommand() != null) { -+ builder.executes(redirect.getCommand()); -+ } -+ // Diff copied from LiteralCommand#createBuilder -+ for (CommandNode child : redirect.getChildren()) { -+ builder.then(child); -+ } -+ -+ argumentBuilder = builder; -+ } -+ // Paper end argumentBuilder.requires(suggestions -> true); - if (argumentBuilder.getCommand() != null) { +- if (argumentBuilder.getCommand() != null) { - argumentBuilder.executes(commandContext -> 0); -+ // Paper start - fix suggestions due to falsely equal nodes -+ // Always create a new instance -+ //noinspection Convert2Lambda -+ argumentBuilder.executes(new com.mojang.brigadier.Command<>() { -+ @Override -+ public int run(com.mojang.brigadier.context.CommandContext commandContext) { -+ return 0; -+ } -+ }); -+ // Paper end - fix suggestions due to falsely equal nodes - } +- } ++ // Paper - don't replace Command instance on suggestion node ++ // we want the exact command instance to be used for equality checks ++ // when assigning serialization ids to each command node if (argumentBuilder instanceof RequiredArgumentBuilder) { + RequiredArgumentBuilder requiredArgumentBuilder = (RequiredArgumentBuilder)argumentBuilder; @@ -396,7 +_,7 @@ commandNodeToSuggestionNode.put(commandNode, commandNode1); rootSuggestion.addChild(commandNode1); diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java index 74d7b1962..51cd38582 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/ApiMirrorRootNode.java @@ -124,7 +124,7 @@ public abstract class ApiMirrorRootNode extends RootCommandNode nativeWrapperArgumentType) { + } else if (pureArgumentType instanceof final VanillaArgumentProviderImpl.NativeWrapperArgumentType nativeWrapperArgumentType) { converted = this.unwrapArgumentWrapper(pureArgumentNode, nativeWrapperArgumentType, nativeWrapperArgumentType, null); // "null" for suggestion provider so it uses the argument type's suggestion provider /* @@ -140,6 +140,8 @@ public abstract class ApiMirrorRootNode extends RootCommandNode argumentCommandNode = node; @@ -49,8 +45,8 @@ public final class PaperBrigadier { } Map, String> map = PaperCommands.INSTANCE.getDispatcherInternal().getSmartUsage(argumentCommandNode, DUMMY); - String usage = map.isEmpty() ? pluginCommandNode.getUsageText() : pluginCommandNode.getUsageText() + " " + String.join("\n" + pluginCommandNode.getUsageText() + " ", map.values()); - return new PluginVanillaCommandWrapper(pluginCommandNode.getName(), pluginCommandNode.getDescription(), usage, pluginCommandNode.getAliases(), node, pluginCommandNode.getPlugin()); + String usage = map.isEmpty() ? node.getUsageText() : node.getUsageText() + " " + String.join("\n" + node.getUsageText() + " ", map.values()); + return new PluginVanillaCommandWrapper(node.getName(), meta.description(), usage, meta.aliases(), node, meta.plugin()); } /* @@ -70,4 +66,19 @@ public final class PaperBrigadier { } } } + + public static LiteralCommandNode copyLiteral(final String newLiteral, final LiteralCommandNode source) { + // logic copied from LiteralCommandNode#createBuilder + final LiteralArgumentBuilder copyBuilder = LiteralArgumentBuilder.literal(newLiteral) + .requires(source.getRequirement()) + .forward(source.getRedirect(), source.getRedirectModifier(), source.isFork()); + if (source.getCommand() != null) { + copyBuilder.executes(source.getCommand()); + } + + for (final CommandNode child : source.getChildren()) { + copyBuilder.then(child); + } + return copyBuilder.build(); + } } 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 95d3b42cb..f9a370433 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 @@ -21,23 +21,20 @@ import java.util.Set; import net.minecraft.commands.CommandBuildContext; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.checkerframework.framework.qual.DefaultQualifier; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import static java.util.Objects.requireNonNull; -@DefaultQualifier(NonNull.class) +@NullMarked public class PaperCommands implements Commands, PaperRegistrar { public static final PaperCommands INSTANCE = new PaperCommands(); private @Nullable LifecycleEventOwner currentContext; - private @MonotonicNonNull CommandDispatcher dispatcher; - private @MonotonicNonNull CommandBuildContext buildContext; + private @Nullable CommandDispatcher dispatcher; + private @Nullable CommandBuildContext buildContext; private boolean invalid = false; @Override @@ -93,65 +90,47 @@ public class PaperCommands implements Commands, PaperRegistrar registerWithFlags(@NotNull final PluginMeta pluginMeta, @NotNull final LiteralCommandNode node, @org.jetbrains.annotations.Nullable final String description, @NotNull final Collection aliases, @NotNull final Set flags) { - final boolean hasFlattenRedirectFlag = flags.contains(CommandRegistrationFlag.FLATTEN_ALIASES); + public @Unmodifiable Set 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); final String literal = node.getLiteral(); - final PluginCommandNode pluginLiteral = new PluginCommandNode(identifier + ":" + literal, pluginMeta, node, description); // Treat the keyed version of the command as the root + final LiteralCommandNode pluginLiteral = PaperBrigadier.copyLiteral(identifier + ":" + literal, node); final Set registeredLabels = new HashSet<>(aliases.size() * 2 + 2); if (this.registerIntoDispatcher(pluginLiteral, true)) { registeredLabels.add(pluginLiteral.getLiteral()); } - if (this.registerRedirect(literal, pluginMeta, pluginLiteral, description, true, hasFlattenRedirectFlag)) { // Plugin commands should override vanilla commands + if (this.registerIntoDispatcher(node, true)) { // Plugin commands should override vanilla commands registeredLabels.add(literal); } // Add aliases final List registeredAliases = new ArrayList<>(aliases.size() * 2); for (final String alias : aliases) { - if (this.registerRedirect(alias, pluginMeta, pluginLiteral, description, false, hasFlattenRedirectFlag)) { + if (this.registerCopy(alias, pluginLiteral, meta)) { registeredAliases.add(alias); } - if (this.registerRedirect(identifier + ":" + alias, pluginMeta, pluginLiteral, description, false, hasFlattenRedirectFlag)) { + if (this.registerCopy(identifier + ":" + alias, pluginLiteral, meta)) { registeredAliases.add(identifier + ":" + alias); } } - if (!registeredAliases.isEmpty()) { - pluginLiteral.setAliases(registeredAliases); - } + pluginLiteral.pluginCommandMeta = new PluginCommandMeta(pluginMeta, description, registeredAliases); registeredLabels.addAll(registeredAliases); return registeredLabels.isEmpty() ? Collections.emptySet() : Collections.unmodifiableSet(registeredLabels); } - private boolean registerRedirect(final String aliasLiteral, final PluginMeta plugin, final PluginCommandNode redirectTo, final @Nullable String description, final boolean override, boolean hasFlattenRedirectFlag) { - final LiteralCommandNode redirect; - if (redirectTo.getChildren().isEmpty() || hasFlattenRedirectFlag) { - redirect = Commands.literal(aliasLiteral) - .executes(redirectTo.getCommand()) - .requires(redirectTo.getRequirement()) - .build(); - - for (final CommandNode child : redirectTo.getChildren()) { - redirect.addChild(child); - } - } else { - redirect = Commands.literal(aliasLiteral) - .executes(redirectTo.getCommand()) - .redirect(redirectTo) - .requires(redirectTo.getRequirement()) - .build(); - } - - return this.registerIntoDispatcher(new PluginCommandNode(aliasLiteral, plugin, redirect, description), override); + private boolean registerCopy(final String aliasLiteral, final LiteralCommandNode redirectTo, final PluginCommandMeta meta) { + final LiteralCommandNode node = PaperBrigadier.copyLiteral(aliasLiteral, redirectTo); + node.pluginCommandMeta = meta; + return this.registerIntoDispatcher(node, false); } - private boolean registerIntoDispatcher(final PluginCommandNode node, boolean override) { - final @Nullable CommandNode existingChild = this.getDispatcher().getRoot().getChild(node.getLiteral()); - if (existingChild != null && !(existingChild instanceof PluginCommandNode) && !(existingChild instanceof BukkitCommandNode)) { + 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)) { 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 new file mode 100644 index 000000000..45701bcca --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandMeta.java @@ -0,0 +1,26 @@ +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/PluginCommandNode.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandNode.java deleted file mode 100644 index 3a9f58873..000000000 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PluginCommandNode.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.papermc.paper.command.brigadier; - -import com.mojang.brigadier.tree.CommandNode; -import com.mojang.brigadier.tree.LiteralCommandNode; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import io.papermc.paper.plugin.configuration.PluginMeta; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class PluginCommandNode extends LiteralCommandNode { - - private final PluginMeta plugin; - private final String description; - private List aliases = Collections.emptyList(); - - public PluginCommandNode(final @NotNull String literal, final @NotNull PluginMeta plugin, final @NotNull LiteralCommandNode rootLiteral, final @Nullable String description) { - super( - literal, rootLiteral.getCommand(), rootLiteral.getRequirement(), - rootLiteral.getRedirect(), rootLiteral.getRedirectModifier(), rootLiteral.isFork() - ); - this.plugin = plugin; - this.description = description; - - for (CommandNode argument : rootLiteral.getChildren()) { - this.addChild(argument); - } - } - - @NotNull - public Plugin getPlugin() { - return Objects.requireNonNull(Bukkit.getPluginManager().getPlugin(this.plugin.getName())); - } - - @NotNull - public String getDescription() { - return this.description; - } - - public void setAliases(List aliases) { - this.aliases = aliases; - } - - public List getAliases() { - return this.aliases; - } -} From 8eb8e44ac32a99f53da7af50e800ac8831030580 Mon Sep 17 00:00:00 2001 From: Miles <81843550+Y2Kwastaken@users.noreply.github.com> Date: Sun, 16 Feb 2025 22:07:00 +0000 Subject: [PATCH 128/203] Allow For Default Titles in InventoryView Builders (#12013) --- .../java/org/bukkit/inventory/MenuType.java | 39 +++++++++------ .../view/builder/InventoryViewBuilder.java | 5 +- .../builder/LocationInventoryViewBuilder.java | 4 +- .../builder/MerchantInventoryViewBuilder.java | 4 +- .../world/level/block/ChestBlock.java.patch | 8 +++- .../block/entity/ChestBlockEntity.java.patch | 9 ++++ .../org/bukkit/craftbukkit/CraftServer.java | 2 +- .../craftbukkit/inventory/CraftMenuType.java | 2 +- .../inventory/CraftMerchantCustom.java | 10 ++++ .../inventory/util/CraftMenus.java | 20 ++++---- .../CraftAbstractInventoryViewBuilder.java | 13 ++--- ...tAbstractLocationInventoryViewBuilder.java | 2 +- ...aftAccessLocationInventoryViewBuilder.java | 31 ++++++++---- .../CraftBlockEntityInventoryViewBuilder.java | 48 ++++++++++++++----- .../CraftDoubleChestInventoryViewBuilder.java | 7 ++- .../CraftEnchantmentInventoryViewBuilder.java | 40 ++++++++++++++++ .../CraftMerchantInventoryViewBuilder.java | 25 +++++++--- .../CraftStandardInventoryViewBuilder.java | 2 + 18 files changed, 201 insertions(+), 70 deletions(-) create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftEnchantmentInventoryViewBuilder.java diff --git a/paper-api/src/main/java/org/bukkit/inventory/MenuType.java b/paper-api/src/main/java/org/bukkit/inventory/MenuType.java index 2442361ce..eb64a5ef2 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/MenuType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/MenuType.java @@ -1,5 +1,6 @@ package org.bukkit.inventory; +import net.kyori.adventure.text.Component; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.Registry; @@ -18,12 +19,14 @@ import org.bukkit.inventory.view.builder.InventoryViewBuilder; import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; import org.bukkit.inventory.view.builder.MerchantInventoryViewBuilder; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents different kinds of views, also known as menus, which can be * created and viewed by the player. */ +@NullMarked @ApiStatus.Experimental public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDependant { // Paper - make FeatureDependant @@ -138,6 +141,20 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe */ interface Typed> extends MenuType { + /** + * Creates a view of the specified menu type. + *

+ * The player provided to create this view must be the player the view + * is opened for. See {@link HumanEntity#openInventory(InventoryView)} + * for more information. + * + * @param player the player the view belongs to + * @return the created {@link InventoryView} + */ + default V create(HumanEntity player) { + return create(player, (Component) null); + } + /** * Creates a view of the specified menu type. *

@@ -148,11 +165,10 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * @param player the player the view belongs to * @param title the title of the view * @return the created {@link InventoryView} - * @deprecated Use {@link #create(HumanEntity, net.kyori.adventure.text.Component)} instead. + * @deprecated Use {@link #create(HumanEntity, Component)} instead. */ - @NotNull @Deprecated(since = "1.21") // Paper - adventure - V create(@NotNull HumanEntity player, @NotNull String title); + V create(HumanEntity player, @Nullable String title); // Paper start - adventure /** @@ -166,11 +182,9 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * @param title the title of the view * @return the created {@link InventoryView} */ - @NotNull - V create(@NotNull HumanEntity player, @NotNull net.kyori.adventure.text.Component title); + V create(HumanEntity player, @Nullable Component title); // Paper end - adventure - @NotNull B builder(); } @@ -186,8 +200,7 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * @param title the title of the view * @return the created {@link InventoryView} */ - @NotNull - InventoryView create(@NotNull HumanEntity player, @NotNull net.kyori.adventure.text.Component title); + InventoryView create(HumanEntity player, @Nullable Component title); // Paper end - adventure /** @@ -196,7 +209,6 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * * @return the typed MenuType. */ - @NotNull MenuType.Typed> typed(); /** @@ -213,19 +225,16 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe * @throws IllegalArgumentException if the provided viewClass cannot be * typed to this MenuType */ - @NotNull - > MenuType.Typed typed(@NotNull final Class viewClass) throws IllegalArgumentException; + > MenuType.Typed typed(final Class viewClass) throws IllegalArgumentException; /** * Gets the {@link InventoryView} class of this MenuType. * * @return the {@link InventoryView} class of this MenuType */ - @NotNull Class getInventoryViewClass(); - @NotNull - private static T get(@NotNull final String key) { + private static T get(final String key) { return (T) Registry.MENU.getOrThrow(NamespacedKey.minecraft(key)); } } diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java index 9f0752228..28e52e7da 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/InventoryViewBuilder.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.InventoryView; import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.Nullable; /** * Generic Builder for InventoryView's with no special attributes or parameters @@ -23,10 +24,10 @@ public interface InventoryViewBuilder { /** * Sets the title of the builder * - * @param title the title + * @param title the title, or null for a default title * @return this builder */ - InventoryViewBuilder title(final Component title); + InventoryViewBuilder title(@Nullable final Component title); /** * Builds this builder into a InventoryView diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java index 9666aa356..a53249727 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/LocationInventoryViewBuilder.java @@ -4,7 +4,7 @@ import net.kyori.adventure.text.Component; import org.bukkit.Location; import org.bukkit.inventory.InventoryView; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; /** * An InventoryViewBuilder that can be bound by location within the world @@ -18,7 +18,7 @@ public interface LocationInventoryViewBuilder extends I LocationInventoryViewBuilder copy(); @Override - LocationInventoryViewBuilder title(final @NotNull Component title); + LocationInventoryViewBuilder title(final @Nullable Component title); /** * Determines whether or not the server should check if the player can reach diff --git a/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java b/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java index 76aecb54a..a8e4e9f18 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java +++ b/paper-api/src/main/java/org/bukkit/inventory/view/builder/MerchantInventoryViewBuilder.java @@ -5,7 +5,7 @@ import org.bukkit.Server; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.Merchant; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; /** * An InventoryViewBuilder for creating merchant views @@ -19,7 +19,7 @@ public interface MerchantInventoryViewBuilder extends I MerchantInventoryViewBuilder copy(); @Override - MerchantInventoryViewBuilder title(final @NotNull Component title); + MerchantInventoryViewBuilder title(final @Nullable Component title); /** * Adds a merchant to this builder diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch index 5ec5cd486..7b27fcf64 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch @@ -9,8 +9,12 @@ @Nullable @Override public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { -@@ -106,7 +_,7 @@ - return (Component)(second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble")); +@@ -103,10 +_,10 @@ + if (first.hasCustomName()) { + return first.getDisplayName(); + } else { +- return (Component)(second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble")); ++ return (Component)(second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble")); // Paper - diff on change - CraftDoubleChestInventoryViewBuilder.defaultTitle } } - }); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch index 32a967c2c..b8ba6305b 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/ChestBlockEntity.java.patch @@ -37,3 +37,12 @@ protected ChestBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { super(type, pos, blockState); } +@@ -71,7 +_,7 @@ + + @Override + protected Component getDefaultName() { +- return Component.translatable("container.chest"); ++ return Component.translatable("container.chest"); // Paper - diff on change - CraftStandardInventoryViewBuilder.defaultTitle + } + + @Override 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 cf5bcb0eb..59eddee7e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -2479,7 +2479,7 @@ public final class CraftServer implements Server { @Override public @NotNull Merchant createMerchant() { - return new CraftMerchantCustom(net.kyori.adventure.text.Component.empty()); + return new CraftMerchantCustom(); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java index 4c6cf43ce..326b62c85 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMenuType.java @@ -38,7 +38,7 @@ public class CraftMenuType(InventoryView.class, () -> new CraftDoubleChestInventoryViewBuilder<>(handle))); } if (menuType == MenuType.GENERIC_9X3) { - return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, null))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CHEST, ChestBlockEntity::new, false))); } // this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9 // this needs to be removed when inventory creation is overhauled @@ -98,7 +100,7 @@ public final class CraftMenus { return asType(new MenuTypeData<>(CrafterView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.CRAFTER, CrafterBlockEntity::new))); } if (menuType == MenuType.ANVIL) { - return asType(new MenuTypeData<>(AnvilView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, AnvilMenu::new))); + return asType(new MenuTypeData<>(AnvilView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.ANVIL))); } if (menuType == MenuType.BEACON) { return asType(new MenuTypeData<>(BeaconView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BEACON, BeaconBlockEntity::new))); @@ -110,16 +112,16 @@ public final class CraftMenus { return asType(new MenuTypeData<>(BrewingStandView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.BREWING_STAND, BrewingStandBlockEntity::new))); } if (menuType == MenuType.CRAFTING) { - return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, CraftingMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.CRAFTING_TABLE))); } if (menuType == MenuType.ENCHANTMENT) { - return asType(new MenuTypeData<>(EnchantmentView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, EnchantmentMenu::new))); + return asType(new MenuTypeData<>(EnchantmentView.class, () -> new CraftEnchantmentInventoryViewBuilder(handle))); } if (menuType == MenuType.FURNACE) { return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.FURNACE, FurnaceBlockEntity::new))); } if (menuType == MenuType.GRINDSTONE) { - return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, GrindstoneMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.GRINDSTONE))); } // We really don't need to be creating a tile entity for hopper but currently InventoryType doesn't have capacity // to understand otherwise @@ -131,7 +133,7 @@ public final class CraftMenus { return asType(new MenuTypeData<>(LecternView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.LECTERN, LecternBlockEntity::new))); } if (menuType == MenuType.LOOM) { - return asType(new MenuTypeData<>(LoomView.class, () -> new CraftStandardInventoryViewBuilder<>(handle))); + return asType(new MenuTypeData<>(LoomView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.LOOM))); } if (menuType == MenuType.MERCHANT) { return asType(new MenuTypeData<>(MerchantView.class, () -> new CraftMerchantInventoryViewBuilder<>(handle))); @@ -140,16 +142,16 @@ public final class CraftMenus { return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SHULKER_BOX, ShulkerBoxBlockEntity::new))); } if (menuType == MenuType.SMITHING) { - return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, SmithingMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.SMITHING_TABLE))); } if (menuType == MenuType.SMOKER) { return asType(new MenuTypeData<>(FurnaceView.class, () -> new CraftBlockEntityInventoryViewBuilder<>(handle, Blocks.SMOKER, SmokerBlockEntity::new))); } if (menuType == MenuType.CARTOGRAPHY_TABLE) { - return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, CartographyTableMenu::new))); + return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.CARTOGRAPHY_TABLE))); } if (menuType == MenuType.STONECUTTER) { - return asType(new MenuTypeData<>(StonecutterView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, StonecutterMenu::new))); + return asType(new MenuTypeData<>(StonecutterView.class, () -> new CraftAccessLocationInventoryViewBuilder<>(handle, Blocks.STONECUTTER))); } return asType(new MenuTypeData<>(InventoryView.class, () -> new CraftStandardInventoryViewBuilder<>(handle))); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java index 185ad0fc1..ef1abf7bf 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractInventoryViewBuilder.java @@ -10,21 +10,22 @@ import org.bukkit.craftbukkit.entity.CraftHumanEntity; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.view.builder.InventoryViewBuilder; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; +import org.jspecify.annotations.Nullable; public abstract class CraftAbstractInventoryViewBuilder implements InventoryViewBuilder { protected final MenuType handle; protected boolean checkReachable = false; - protected @MonotonicNonNull Component title = null; + protected @Nullable Component title = null; + protected net.minecraft.network.chat.Component defaultTitle = null; public CraftAbstractInventoryViewBuilder(final MenuType handle) { this.handle = handle; } @Override - public InventoryViewBuilder title(final Component title) { + public InventoryViewBuilder title(final @Nullable Component title) { this.title = title; return this; } @@ -33,14 +34,14 @@ public abstract class CraftAbstractInventoryViewBuilder @Override public V build(final HumanEntity player) { Preconditions.checkArgument(player != null, "The given player must not be null"); - Preconditions.checkArgument(this.title != null, "The given title must not be null"); Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity"); final CraftHumanEntity craftHuman = (CraftHumanEntity) player; - Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer"); + Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an ServerPlayer"); final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle(); + final AbstractContainerMenu container = buildContainer(serverPlayer); container.checkReachable = this.checkReachable; - container.setTitle(PaperAdventure.asVanilla(this.title)); + container.setTitle(this.title != null ? PaperAdventure.asVanilla(this.title) : this.defaultTitle); return (V) container.getBukkitView(); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java index 7a894ca07..15f1b3016 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAbstractLocationInventoryViewBuilder.java @@ -22,7 +22,7 @@ public abstract class CraftAbstractLocationInventoryViewBuilder title(final Component title) { + public LocationInventoryViewBuilder title(final @Nullable Component title) { return (LocationInventoryViewBuilder) super.title(title); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java index 096f3ebf8..8e0d45319 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftAccessLocationInventoryViewBuilder.java @@ -1,37 +1,50 @@ package org.bukkit.craftbukkit.inventory.view.builder; +import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.ContainerLevelAccess; import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.view.builder.LocationInventoryViewBuilder; public class CraftAccessLocationInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder { - private final CraftAccessContainerObjectBuilder containerBuilder; + private final Block block; - public CraftAccessLocationInventoryViewBuilder(final MenuType handle, final CraftAccessContainerObjectBuilder containerBuilder) { + public CraftAccessLocationInventoryViewBuilder(final MenuType handle, final Block block) { super(handle); - this.containerBuilder = containerBuilder; + this.block = block; } @Override protected AbstractContainerMenu buildContainer(final ServerPlayer player) { - final ContainerLevelAccess access; - if (super.position == null) { - access = ContainerLevelAccess.create(player.level(), player.blockPosition()); + final BlockState effectiveBlockState; + final BlockPos effectiveBlockPos; + final Level effectiveLevel; + if (super.position != null) { + effectiveBlockPos = super.position; + effectiveLevel = super.world; + effectiveBlockState = super.world.getBlockState(position); } else { - access = ContainerLevelAccess.create(super.world, super.position); + effectiveBlockPos = player.blockPosition(); + effectiveLevel = player.level(); + effectiveBlockState = block.defaultBlockState(); } - return this.containerBuilder.build(player.nextContainerCounter(), player.getInventory(), access); + final MenuProvider provider = block.getMenuProvider(effectiveBlockState, effectiveLevel, effectiveBlockPos); + super.defaultTitle = provider.getDisplayName(); + return provider.createMenu(player.nextContainerCounter(), player.getInventory(), player); } @Override public LocationInventoryViewBuilder copy() { - final CraftAccessLocationInventoryViewBuilder copy = new CraftAccessLocationInventoryViewBuilder<>(this.handle, this.containerBuilder); + final CraftAccessLocationInventoryViewBuilder copy = new CraftAccessLocationInventoryViewBuilder<>(this.handle, this.block); copy.world = super.world; copy.position = super.position; copy.checkReachable = super.checkReachable; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java index 262581444..b555d5078 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftBlockEntityInventoryViewBuilder.java @@ -16,10 +16,25 @@ import org.jspecify.annotations.Nullable; public class CraftBlockEntityInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder { private final Block block; - private final @Nullable CraftTileInventoryBuilder builder; + private final boolean useFakeBlockEntity; + private final @Nullable CraftBlockInventoryBuilder builder; - public CraftBlockEntityInventoryViewBuilder(final MenuType handle, final Block block, final @Nullable CraftTileInventoryBuilder builder) { + public CraftBlockEntityInventoryViewBuilder( + final MenuType handle, + final Block block, + final @Nullable CraftBlockInventoryBuilder builder + ) { + this(handle, block, builder, true); + } + + public CraftBlockEntityInventoryViewBuilder( + final MenuType handle, + final Block block, + final @Nullable CraftBlockInventoryBuilder builder, + final boolean useFakeBlockEntity + ) { super(handle); + this.useFakeBlockEntity = useFakeBlockEntity; this.block = block; this.builder = builder; } @@ -32,35 +47,44 @@ public class CraftBlockEntityInventoryViewBuilder exten if (this.position == null) { this.position = player.blockPosition(); + return buildFakeBlockEntity(player); } final BlockEntity entity = this.world.getBlockEntity(position); if (!(entity instanceof final MenuConstructor container)) { - return buildFakeTile(player); + return buildFakeBlockEntity(player); } final AbstractContainerMenu atBlock = container.createMenu(player.nextContainerCounter(), player.getInventory(), player); if (atBlock.getType() != super.handle) { - return buildFakeTile(player); + return buildFakeBlockEntity(player); } + if (!(entity instanceof final MenuProvider provider)) { + throw new IllegalStateException("Provided blockEntity during MenuType creation can not find a default title! This is a bug!"); + } + + super.defaultTitle = provider.getDisplayName(); return atBlock; } - private AbstractContainerMenu buildFakeTile(final ServerPlayer player) { - if (this.builder == null) { + private AbstractContainerMenu buildFakeBlockEntity(final ServerPlayer player) { + final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState()); + if (inventory instanceof final BlockEntity blockEntity) { + blockEntity.setLevel(this.world); + super.defaultTitle = inventory.getDisplayName(); + } + + if (!this.useFakeBlockEntity) { // gets around open noise for chest return handle.create(player.nextContainerCounter(), player.getInventory()); } - final MenuProvider inventory = this.builder.build(this.position, this.block.defaultBlockState()); - if (inventory instanceof final BlockEntity tile) { - tile.setLevel(this.world); - } + return inventory.createMenu(player.nextContainerCounter(), player.getInventory(), player); } @Override public LocationInventoryViewBuilder copy() { - final CraftBlockEntityInventoryViewBuilder copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder); + final CraftBlockEntityInventoryViewBuilder copy = new CraftBlockEntityInventoryViewBuilder<>(super.handle, this.block, this.builder, this.useFakeBlockEntity); copy.world = this.world; copy.position = this.position; copy.checkReachable = super.checkReachable; @@ -68,7 +92,7 @@ public class CraftBlockEntityInventoryViewBuilder exten return copy; } - public interface CraftTileInventoryBuilder { + public interface CraftBlockInventoryBuilder { MenuProvider build(BlockPos blockPosition, BlockState blockData); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java index 331e3797a..f0133272d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftDoubleChestInventoryViewBuilder.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.inventory.view.builder; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.MenuProvider; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -15,6 +16,7 @@ public class CraftDoubleChestInventoryViewBuilder exten public CraftDoubleChestInventoryViewBuilder(final MenuType handle) { super(handle); + super.defaultTitle = Component.translatable("container.chestDouble"); } @Override @@ -24,7 +26,9 @@ public class CraftDoubleChestInventoryViewBuilder exten } final ChestBlock chest = (ChestBlock) Blocks.CHEST; - final DoubleBlockCombiner.NeighborCombineResult result = chest.combine(super.world.getBlockState(super.position), super.world, super.position, false); + final DoubleBlockCombiner.NeighborCombineResult result = chest.combine( + super.world.getBlockState(super.position), super.world, super.position, false + ); if (result instanceof DoubleBlockCombiner.NeighborCombineResult.Single) { return handle.create(player.nextContainerCounter(), player.getInventory()); } @@ -33,6 +37,7 @@ public class CraftDoubleChestInventoryViewBuilder exten if (combined == null) { return handle.create(player.nextContainerCounter(), player.getInventory()); } + return combined.createMenu(player.nextContainerCounter(), player.getInventory(), player); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftEnchantmentInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftEnchantmentInventoryViewBuilder.java new file mode 100644 index 000000000..6f5029415 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftEnchantmentInventoryViewBuilder.java @@ -0,0 +1,40 @@ +package org.bukkit.craftbukkit.inventory.view.builder; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.EnchantmentMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.EnchantingTableBlockEntity; +import org.bukkit.inventory.view.EnchantmentView; + +public class CraftEnchantmentInventoryViewBuilder extends CraftAbstractLocationInventoryViewBuilder { + + public CraftEnchantmentInventoryViewBuilder(final MenuType handle) { + super(handle); + } + + @Override + protected AbstractContainerMenu buildContainer(final ServerPlayer player) { + if (this.world == null) { + this.world = player.level(); + } + + if (this.position == null) { + this.position = player.blockPosition(); + super.defaultTitle = new EnchantingTableBlockEntity(this.position, Blocks.ENCHANTING_TABLE.defaultBlockState()).getDisplayName(); + return new EnchantmentMenu(player.nextContainerCounter(), player.getInventory(), ContainerLevelAccess.create(this.world, this.position)); + } + + final BlockEntity entity = this.world.getBlockEntity(position); + if (entity instanceof final EnchantingTableBlockEntity enchantingBlockEntity) { + super.defaultTitle = enchantingBlockEntity.getDisplayName(); + } else { + super.defaultTitle = new EnchantingTableBlockEntity(this.position, Blocks.ENCHANTING_TABLE.defaultBlockState()).getDisplayName(); + } + + return new EnchantmentMenu(player.nextContainerCounter(), player.getInventory(), ContainerLevelAccess.create(this.world, this.position)); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java index 7f7518aa7..d46f942e1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftMerchantInventoryViewBuilder.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import io.papermc.paper.adventure.PaperAdventure; import net.kyori.adventure.text.Component; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.npc.AbstractVillager; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MerchantMenu; @@ -25,7 +26,7 @@ public class CraftMerchantInventoryViewBuilder extends } @Override - public MerchantInventoryViewBuilder title(final Component title) { + public MerchantInventoryViewBuilder title(final @Nullable Component title) { return (MerchantInventoryViewBuilder) super.title(title); } @@ -44,24 +45,34 @@ public class CraftMerchantInventoryViewBuilder extends @Override public V build(final HumanEntity player) { Preconditions.checkArgument(player != null, "The given player must not be null"); - Preconditions.checkArgument(this.title != null, "The given title must not be null"); Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity"); final CraftHumanEntity craftHuman = (CraftHumanEntity) player; - Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an EntityPlayer"); + Preconditions.checkArgument(craftHuman.getHandle() instanceof ServerPlayer, "The given player must be an ServerPlayer"); final ServerPlayer serverPlayer = (ServerPlayer) craftHuman.getHandle(); final MerchantMenu container; if (this.merchant == null) { - container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), new CraftMerchantCustom(title).getMerchant()); - } else { - container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), this.merchant); + this.merchant = this.title == null ? new CraftMerchantCustom().getMerchant() : new CraftMerchantCustom(title).getMerchant(); } + container = new MerchantMenu(serverPlayer.nextContainerCounter(), serverPlayer.getInventory(), this.merchant); + container.checkReachable = super.checkReachable; - container.setTitle(PaperAdventure.asVanilla(this.title)); + setDefaultTitle(this.merchant); + container.setTitle(super.title != null ? PaperAdventure.asVanilla(this.title) : super.defaultTitle); return (V) container.getBukkitView(); } + private void setDefaultTitle(final net.minecraft.world.item.trading.Merchant merchant) { + if (merchant instanceof final AbstractVillager villager) { + super.defaultTitle = villager.getDisplayName(); + } else if (merchant instanceof final CraftMerchantCustom.MinecraftMerchant custom) { + super.defaultTitle = custom.getScoreboardDisplayName(); + } else { + throw new IllegalStateException("Provided merchant during MenuType creation can not find a default title! This is a bug!"); + } + } + @Override protected AbstractContainerMenu buildContainer(final ServerPlayer player) { throw new UnsupportedOperationException("buildContainer is not supported for CraftMerchantInventoryViewBuilder"); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java index e528facbe..670f79d00 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/builder/CraftStandardInventoryViewBuilder.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.inventory.view.builder; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; @@ -10,6 +11,7 @@ public class CraftStandardInventoryViewBuilder extends public CraftStandardInventoryViewBuilder(final MenuType handle) { super(handle); + super.defaultTitle = Component.translatable("container.chest"); } @Override From fd69140d80ca4158914bcc800bb82ace2d8c4ba0 Mon Sep 17 00:00:00 2001 From: Dqu1J Date: Mon, 17 Feb 2025 19:07:02 +0000 Subject: [PATCH 129/203] Fix `disable-tripwire-updates` option not cancelling tripwire hook updates (#12129) --- .../world/level/block/TripWireHookBlock.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch index b2b90b416..909de7ef6 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/TripWireHookBlock.java.patch @@ -63,3 +63,12 @@ if (flag != flag2) { for (int i2 = 1; i2 < i; i2++) { +@@ -189,7 +_,7 @@ + if (blockState2 != null) { + BlockState blockState3 = level.getBlockState(blockPos1); + if (blockState3.is(Blocks.TRIPWIRE) || blockState3.is(Blocks.TRIPWIRE_HOOK)) { +- level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3); ++ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableTripwireUpdates || !blockState3.is(Blocks.TRIPWIRE)) level.setBlock(blockPos1, blockState2.trySetValue(ATTACHED, Boolean.valueOf(flag2)), 3); // Paper - prevent tripwire from updating + } + } + } From 3b9106c7d138f5ae99eb51834e768f1441a41bb2 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Mon, 17 Feb 2025 23:51:52 +0100 Subject: [PATCH 130/203] Readd dead redirect recovery (#12136) While the paper command system no longer uses redirects for namespaced registration, vanilla still does. This means that removal of vanilla redirecting target nodes still causes issues, e.g. the removal of the vanilla 'msg' node in favour of a command alias one. Redirecting nodes like tell, minecraft:msg and minecraft:tell are broken by this and need to by flattened before sending them to the client. --- .../minecraft/commands/Commands.java.patch | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) 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 b5fdc04cc..dff5340ad 100644 --- a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch @@ -144,7 +144,7 @@ } return null; -@@ -360,26 +_,85 @@ +@@ -360,26 +_,120 @@ } public void sendCommands(ServerPlayer player) { @@ -226,6 +226,41 @@ + if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot if (commandNode.canUse(source)) { ArgumentBuilder argumentBuilder = (ArgumentBuilder) commandNode.createBuilder(); ++ // Paper start ++ /* ++ Because of how commands can be yeeted right left and center due to bad bukkit practices ++ we need to be able to ensure that ALL commands are registered (even redirects). ++ ++ What this will do is IF the redirect seems to be "dead" it will create a builder and essentially populate (flatten) ++ all the children from the dead redirect to the node. ++ ++ So, if minecraft:msg redirects to msg but the original msg node has been overriden minecraft:msg will now act as msg and will explicilty inherit its children. ++ ++ The only way to fix this is to either: ++ - Send EVERYTHING flattened, don't use redirects ++ - Don't allow command nodes to be deleted ++ - Do this :) ++ */ ++ // Is there an invalid command redirect? ++ if (argumentBuilder.getRedirect() != null && commandNodeToSuggestionNode.get(argumentBuilder.getRedirect()) == null) { ++ // Create the argument builder with the same values as the specified node, but with a different literal and populated children ++ ++ final CommandNode redirect = argumentBuilder.getRedirect(); ++ // Diff copied from LiteralCommand#createBuilder ++ final com.mojang.brigadier.builder.LiteralArgumentBuilder builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName()); ++ builder.requires(redirect.getRequirement()); ++ // builder.forward(redirect.getRedirect(), redirect.getRedirectModifier(), redirect.isFork()); We don't want to migrate the forward, since it's invalid. ++ if (redirect.getCommand() != null) { ++ builder.executes(redirect.getCommand()); ++ } ++ // Diff copied from LiteralCommand#createBuilder ++ for (final CommandNode child : redirect.getChildren()) { ++ builder.then(child); ++ } ++ ++ argumentBuilder = builder; ++ } ++ // Paper end argumentBuilder.requires(suggestions -> true); - if (argumentBuilder.getCommand() != null) { - argumentBuilder.executes(commandContext -> 0); From d26a9e90c81e87510a68a4cb68d29291468d15f8 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 17 Feb 2025 15:00:06 -0800 Subject: [PATCH 131/203] Fix plugin commands (#12144) --- .../java/io/papermc/paper/command/brigadier/PaperCommands.java | 1 + 1 file changed, 1 insertion(+) 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 f9a370433..4b6d84542 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 @@ -117,6 +117,7 @@ public class PaperCommands implements Commands, PaperRegistrar Date: Tue, 18 Feb 2025 00:09:54 +0100 Subject: [PATCH 132/203] Default minecraft alias to redirect (#12146) While the running server will still be using the recently introduced copy-mechanic for vanilla command namespacing, the data converter logic relies on the fact that namespaced aliases were redirects as well. To not break the converted, the commands type now takes a modern flag only set by the running server. --- .../minecraft/commands/Commands.java.patch | 42 +++++++++++++++---- .../ReloadableServerResources.java.patch | 6 ++- .../DFUCommandArgumentUpgraderCompatTest.java | 17 ++++++++ .../MinecraftCommandPermissionsTest.java | 2 +- 4 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 paper-server/src/test/java/io/papermc/paper/command/brigadier/DFUCommandArgumentUpgraderCompatTest.java 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 dff5340ad..119e3eb76 100644 --- a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch @@ -1,6 +1,18 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -251,6 +_,24 @@ +@@ -150,6 +_,11 @@ + private final CommandDispatcher dispatcher = new CommandDispatcher<>(); + + public Commands(Commands.CommandSelection selection, CommandBuildContext context) { ++ // Paper start - Brigadier API - modern minecraft overloads that do not use redirects but are copies instead ++ this(selection, context, false); ++ } ++ public Commands(Commands.CommandSelection selection, CommandBuildContext context, final boolean modern) { ++ // Paper end - Brigadier API - modern minecraft overloads that do not use redirects but are copies instead + AdvancementCommands.register(this.dispatcher); + AttributeCommand.register(this.dispatcher, context); + ExecuteCommand.register(this.dispatcher, context); +@@ -251,6 +_,40 @@ PublishCommand.register(this.dispatcher); } @@ -14,12 +26,28 @@ + // Paper start - Brigadier Command API + // Create legacy minecraft namespace commands + for (final CommandNode node : new java.util.ArrayList<>(this.dispatcher.getRoot().getChildren())) { -+ this.dispatcher.getRoot().addChild( -+ io.papermc.paper.command.brigadier.PaperBrigadier.copyLiteral( -+ "minecraft:" + node.getName(), -+ (com.mojang.brigadier.tree.LiteralCommandNode) node -+ ) -+ ); ++ if (modern) { ++ // Modern behaviour that simply creates a full copy of the commands node. ++ // Avoids plenty of issues around registering redirects *to* these nodes from the API ++ this.dispatcher.getRoot().addChild( ++ io.papermc.paper.command.brigadier.PaperBrigadier.copyLiteral( ++ "minecraft:" + node.getName(), ++ (com.mojang.brigadier.tree.LiteralCommandNode) node ++ ) ++ ); ++ continue; ++ } ++ ++ // Legacy behaviour of creating a flattened redirecting node. ++ // Used by CommandArgumentUpgrader ++ CommandNode flattenedAliasTarget = node; ++ while (flattenedAliasTarget.getRedirect() != null) flattenedAliasTarget = flattenedAliasTarget.getRedirect(); ++ ++ this.dispatcher.register( ++ com.mojang.brigadier.builder.LiteralArgumentBuilder.literal("minecraft:" + node.getName()) ++ .executes(flattenedAliasTarget.getCommand()) ++ .requires(flattenedAliasTarget.getRequirement()) ++ .redirect(flattenedAliasTarget)); + } + // Paper end - Brigadier Command API this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); 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 dd754adca..caa71bc36 100644 --- a/paper-server/patches/sources/net/minecraft/server/ReloadableServerResources.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/ReloadableServerResources.java.patch @@ -1,9 +1,11 @@ --- a/net/minecraft/server/ReloadableServerResources.java +++ b/net/minecraft/server/ReloadableServerResources.java -@@ -39,6 +_,7 @@ +@@ -38,7 +_,8 @@ + 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)); ++ 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 this.advancements = new ServerAdvancementManager(registries); this.functionLibrary = new ServerFunctionLibrary(functionCompilationLevel, this.commands.getDispatcher()); diff --git a/paper-server/src/test/java/io/papermc/paper/command/brigadier/DFUCommandArgumentUpgraderCompatTest.java b/paper-server/src/test/java/io/papermc/paper/command/brigadier/DFUCommandArgumentUpgraderCompatTest.java new file mode 100644 index 000000000..0d32d772e --- /dev/null +++ b/paper-server/src/test/java/io/papermc/paper/command/brigadier/DFUCommandArgumentUpgraderCompatTest.java @@ -0,0 +1,17 @@ +package io.papermc.paper.command.brigadier; + +import ca.spottedleaf.dataconverter.util.CommandArgumentUpgrader; +import org.bukkit.support.environment.Normal; +import org.junit.jupiter.api.Test; + +@Normal +public class DFUCommandArgumentUpgraderCompatTest { + + @Test + public void testCompatibilityWithCommandArgumentUpgrader() { + // The Command argument upgrader has some specific assumptions about the tree, specifically around + // Attempt to construct it and to that degree its tree of commands. + CommandArgumentUpgrader.upgrader_1_20_4_to_1_20_5(999); + } + +} diff --git a/paper-server/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java b/paper-server/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java index 75ed5050f..fe08e446e 100644 --- a/paper-server/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java +++ b/paper-server/src/test/java/io/papermc/paper/permissions/MinecraftCommandPermissionsTest.java @@ -40,7 +40,7 @@ public class MinecraftCommandPermissionsTest { CraftDefaultPermissions.registerCorePermissions(); Set perms = collectMinecraftCommandPerms(); - Commands commands = new Commands(Commands.CommandSelection.DEDICATED, CommandBuildContext.simple(RegistryHelper.getRegistry(), FeatureFlags.VANILLA_SET)); + Commands commands = new Commands(Commands.CommandSelection.DEDICATED, CommandBuildContext.simple(RegistryHelper.getRegistry(), FeatureFlags.VANILLA_SET), true); RootCommandNode root = commands.getDispatcher().getRoot(); Set missing = new LinkedHashSet<>(); Set foundPerms = new HashSet<>(); From e494f2894ebd51f82aa5c69fb28f895b6f5469fe Mon Sep 17 00:00:00 2001 From: Epic Date: Mon, 17 Feb 2025 23:19:30 +0000 Subject: [PATCH 133/203] Correctly call BlockFadeEvents (#12141) --- .../net/minecraft/world/level/block/FarmBlock.java.patch | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch index fb670445d..7b5e8dcbc 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/FarmBlock.java +++ b/net/minecraft/world/level/block/FarmBlock.java -@@ -95,31 +_,56 @@ +@@ -95,31 +_,59 @@ @Override protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { int moistureValue = state.getValue(MOISTURE); @@ -53,8 +53,11 @@ public static void turnToDirt(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) { + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { -+ return; ++ if (entity == null) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory ++ .callBlockFadeEvent(level, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { ++ return; ++ } + } + // CraftBukkit end BlockState blockState = pushEntitiesUp(state, Blocks.DIRT.defaultBlockState(), level, pos); From b386a8f5273237d2dbe882832ea6c2e3ac0ee0b1 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 17 Feb 2025 15:21:29 -0800 Subject: [PATCH 134/203] Add simpler JavaPlugin command registration (#12142) --- .../org/bukkit/plugin/java/JavaPlugin.java | 140 +++++++++++++----- 1 file changed, 106 insertions(+), 34 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java index a04100646..fa65a03ec 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -2,6 +2,8 @@ package org.bukkit.plugin.java; import com.google.common.base.Charsets; import com.google.common.base.Preconditions; +import io.papermc.paper.command.brigadier.BasicCommand; +import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -11,6 +13,8 @@ import java.io.OutputStream; import java.io.Reader; import java.net.URL; import java.net.URLConnection; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.logging.Level; @@ -26,14 +30,16 @@ import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.PluginBase; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginLoader; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Represents a Java plugin and its main class. It contains fundamental methods * and fields for a plugin to be loaded and work properly. This is an indirect * implementation of {@link org.bukkit.plugin.Plugin}. */ +@NullMarked public abstract class JavaPlugin extends PluginBase { private boolean isEnabled = false; private PluginLoader loader = null; @@ -61,7 +67,7 @@ public abstract class JavaPlugin extends PluginBase { } @Deprecated(forRemoval = true) - protected JavaPlugin(@NotNull final JavaPluginLoader loader, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file) { + protected JavaPlugin(final JavaPluginLoader loader, final PluginDescriptionFile description, final File dataFolder, final File file) { final ClassLoader classLoader = this.getClass().getClassLoader(); if (classLoader instanceof PluginClassLoader) { throw new IllegalStateException("Cannot use initialization constructor at runtime"); @@ -75,7 +81,6 @@ public abstract class JavaPlugin extends PluginBase { * * @return The folder. */ - @NotNull @Override public final File getDataFolder() { return dataFolder; @@ -88,7 +93,6 @@ public abstract class JavaPlugin extends PluginBase { * @deprecated Plugin loading now occurs at a point which makes it impossible to expose this * behavior. This instance will only throw unsupported operation exceptions. */ - @NotNull @Override @Deprecated(forRemoval = true) public final PluginLoader getPluginLoader() { @@ -100,7 +104,6 @@ public abstract class JavaPlugin extends PluginBase { * * @return Server running this plugin */ - @NotNull @Override public final Server getServer() { return server; @@ -121,7 +124,6 @@ public abstract class JavaPlugin extends PluginBase { * * @return File containing this plugin */ - @NotNull protected File getFile() { return file; } @@ -132,19 +134,16 @@ public abstract class JavaPlugin extends PluginBase { * @return Contents of the plugin.yml file * @deprecated No longer applicable to all types of plugins */ - @NotNull @Override @Deprecated public final PluginDescriptionFile getDescription() { return description; } - @NotNull public final io.papermc.paper.plugin.configuration.PluginMeta getPluginMeta() { return this.pluginMeta; } - @NotNull @Override public FileConfiguration getConfig() { if (newConfig == null) { @@ -163,8 +162,7 @@ public abstract class JavaPlugin extends PluginBase { * @throws IllegalArgumentException if file is null * @see ClassLoader#getResourceAsStream(String) */ - @Nullable - protected final Reader getTextResource(@NotNull String file) { + protected final @Nullable Reader getTextResource(String file) { final InputStream in = getResource(file); return in == null ? null : new InputStreamReader(in, Charsets.UTF_8); @@ -199,7 +197,7 @@ public abstract class JavaPlugin extends PluginBase { } @Override - public void saveResource(@NotNull String resourcePath, boolean replace) { + public void saveResource(String resourcePath, boolean replace) { if (resourcePath == null || resourcePath.equals("")) { throw new IllegalArgumentException("ResourcePath cannot be null or empty"); } @@ -236,9 +234,8 @@ public abstract class JavaPlugin extends PluginBase { } } - @Nullable @Override - public InputStream getResource(@NotNull String filename) { + public @Nullable InputStream getResource(String filename) { if (filename == null) { throw new IllegalArgumentException("Filename cannot be null"); } @@ -263,7 +260,6 @@ public abstract class JavaPlugin extends PluginBase { * * @return ClassLoader holding this plugin */ - @NotNull protected final ClassLoader getClassLoader() { return classLoader; } @@ -296,11 +292,11 @@ public abstract class JavaPlugin extends PluginBase { private static final PluginLoader INSTANCE = net.kyori.adventure.util.Services.service(PluginLoader.class) .orElseThrow(); } - public final void init(@NotNull PluginLoader loader, @NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader) { + public final void init(PluginLoader loader, Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader) { init(server, description, dataFolder, file, classLoader, description, com.destroystokyo.paper.utils.PaperPluginLogger.getLogger(description)); this.pluginMeta = description; } - public final void init(@NotNull Server server, @NotNull PluginDescriptionFile description, @NotNull File dataFolder, @NotNull File file, @NotNull ClassLoader classLoader, @Nullable io.papermc.paper.plugin.configuration.PluginMeta configuration, @NotNull Logger logger) { + public final void init(Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader, io.papermc.paper.plugin.configuration.@Nullable PluginMeta configuration, Logger logger) { this.loader = DummyPluginLoaderImplHolder.INSTANCE; this.server = server; this.file = file; @@ -316,7 +312,7 @@ public abstract class JavaPlugin extends PluginBase { * {@inheritDoc} */ @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) { + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { return false; } @@ -324,8 +320,7 @@ public abstract class JavaPlugin extends PluginBase { * {@inheritDoc} */ @Override - @Nullable - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String @NotNull [] args) { + public @Nullable List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { return null; } @@ -337,14 +332,15 @@ public abstract class JavaPlugin extends PluginBase { * @param name name or alias of the command * @return the plugin command if found, otherwise null * @throws UnsupportedOperationException if this plugin is a paper plugin and the method is called in {@link #onEnable()} + * @see #registerCommand(String, String, Collection, BasicCommand) */ - @Nullable - public PluginCommand getCommand(@NotNull String name) { + public @Nullable PluginCommand getCommand(String name) { if (this.isBeingEnabled && !(pluginMeta instanceof PluginDescriptionFile)) { throw new UnsupportedOperationException(""" You are trying to call JavaPlugin#getCommand on a Paper plugin during startup: you are probably trying to get a command you tried to define in paper-plugin.yml. Paper plugins do not support YAML-based command declarations! + You can use JavaPlugin#registerCommand to define commands in Paper plugins. Please check the documentation for more information on how to define commands in Paper plugins: https://docs.papermc.io/paper/dev/getting-started/paper-plugins#commands """); } @@ -362,6 +358,88 @@ public abstract class JavaPlugin extends PluginBase { } } + /** + * Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}. + * + *

Commands have certain overriding behavior: + *

    + *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • + *
  • The main command/namespaced label will override already existing commands
  • + *
+ * + * @param label the label of the to-be-registered command + * @param basicCommand the basic command instance to register + * @see LifecycleEvents#COMMANDS + */ + @ApiStatus.Experimental + public void registerCommand(final String label, final BasicCommand basicCommand) { + this.registerCommand(label, null, Collections.emptyList(), basicCommand); + } + + /** + * Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}. + * + *

Commands have certain overriding behavior: + *

    + *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • + *
  • The main command/namespaced label will override already existing commands
  • + *
+ * + * @param label the label of the to-be-registered command + * @param description the help description for the root literal node + * @param basicCommand the basic command instance to register + * @see LifecycleEvents#COMMANDS + */ + @ApiStatus.Experimental + public void registerCommand(final String label, final @Nullable String description, final BasicCommand basicCommand) { + this.registerCommand(label, description, Collections.emptyList(), basicCommand); + } + + /** + * Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}. + * + *

Commands have certain overriding behavior: + *

    + *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • + *
  • The main command/namespaced label will override already existing commands
  • + *
+ * + * @param label the label of the to-be-registered command + * @param aliases a collection of aliases to register the basic command under. + * @param basicCommand the basic command instance to register + * @see LifecycleEvents#COMMANDS + */ + @ApiStatus.Experimental + public void registerCommand(final String label, final Collection aliases, final BasicCommand basicCommand) { + this.registerCommand(label, null, aliases, basicCommand); + } + + /** + * Registers a command for this plugin. Only valid to be called inside {@link #onEnable()}. + * + *

Commands have certain overriding behavior: + *

    + *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • + *
  • Aliases are not Brigadier redirects, they just copy the command to a different label
  • + *
  • The main command/namespaced label will override already existing commands
  • + *
+ * + * @param label the label of the to-be-registered command + * @param description the help description for the root literal node + * @param aliases a collection of aliases to register the basic command under. + * @param basicCommand the basic command instance to register + * @see LifecycleEvents#COMMANDS + */ + @ApiStatus.Experimental + public void registerCommand(final String label, final @Nullable String description, final Collection aliases, final BasicCommand basicCommand) { + this.getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, event -> { + event.registrar().register(label, description, aliases, basicCommand); + }); + } + @Override public void onLoad() {} @@ -371,15 +449,13 @@ public abstract class JavaPlugin extends PluginBase { @Override public void onEnable() {} - @Nullable @Override - public ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) { + public @Nullable ChunkGenerator getDefaultWorldGenerator(String worldName, @Nullable String id) { return null; } - @Nullable @Override - public BiomeProvider getDefaultBiomeProvider(@NotNull String worldName, @Nullable String id) { + public @Nullable BiomeProvider getDefaultBiomeProvider(String worldName, @Nullable String id) { return null; } @@ -393,13 +469,11 @@ public abstract class JavaPlugin extends PluginBase { this.naggable = canNag; } - @NotNull @Override public Logger getLogger() { return logger; } - @NotNull @Override public String toString() { return description.getFullName(); @@ -428,8 +502,7 @@ public abstract class JavaPlugin extends PluginBase { * @throws ClassCastException if plugin that provided the class does not * extend the class */ - @NotNull - public static T getPlugin(@NotNull Class clazz) { + public static T getPlugin(Class clazz) { Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin"); if (!JavaPlugin.class.isAssignableFrom(clazz)) { throw new IllegalArgumentException(clazz + " does not extend " + JavaPlugin.class); @@ -457,8 +530,7 @@ public abstract class JavaPlugin extends PluginBase { * @throws IllegalStateException if called from the static initializer for * given JavaPlugin */ - @NotNull - public static JavaPlugin getProvidingPlugin(@NotNull Class clazz) { + public static JavaPlugin getProvidingPlugin(Class clazz) { Preconditions.checkArgument(clazz != null, "Null class cannot have a plugin"); final ClassLoader cl = clazz.getClassLoader(); if (!(cl instanceof io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader configuredPluginClassLoader)) { @@ -472,7 +544,7 @@ public abstract class JavaPlugin extends PluginBase { } @Override - public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager() { + public final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager getLifecycleManager() { return this.lifecycleEventManager; } } From f070081825058ec27d040ed32fee71b5b2da5fb3 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Mon, 17 Feb 2025 15:33:26 -0800 Subject: [PATCH 135/203] Remove Experimental from TypedKey (#12134) --- .../generator/types/GeneratedKeyType.java | 3 --- .../paper/registry/keys/AttributeKeys.java | 2 -- .../registry/keys/BannerPatternKeys.java | 3 --- .../paper/registry/keys/BiomeKeys.java | 3 --- .../paper/registry/keys/BlockTypeKeys.java | 2 -- .../paper/registry/keys/CatVariantKeys.java | 2 -- .../paper/registry/keys/DamageTypeKeys.java | 3 --- .../paper/registry/keys/EnchantmentKeys.java | 3 --- .../paper/registry/keys/FluidKeys.java | 2 -- .../paper/registry/keys/FrogVariantKeys.java | 2 -- .../paper/registry/keys/GameEventKeys.java | 3 --- .../paper/registry/keys/InstrumentKeys.java | 3 --- .../paper/registry/keys/ItemTypeKeys.java | 2 -- .../paper/registry/keys/JukeboxSongKeys.java | 3 --- .../registry/keys/MapDecorationTypeKeys.java | 2 -- .../paper/registry/keys/MenuTypeKeys.java | 2 -- .../paper/registry/keys/MobEffectKeys.java | 2 -- .../registry/keys/PaintingVariantKeys.java | 3 --- .../paper/registry/keys/SoundEventKeys.java | 2 -- .../paper/registry/keys/StructureKeys.java | 3 --- .../registry/keys/StructureTypeKeys.java | 2 -- .../paper/registry/keys/TrimMaterialKeys.java | 3 --- .../paper/registry/keys/TrimPatternKeys.java | 3 --- .../registry/keys/VillagerProfessionKeys.java | 2 -- .../paper/registry/keys/VillagerTypeKeys.java | 2 -- .../paper/registry/keys/WolfVariantKeys.java | 3 --- .../papermc/paper/registry/RegistryKey.java | 27 ++++++++++++++++--- .../io/papermc/paper/registry/TypedKey.java | 5 +--- .../io/papermc/paper/registry/tag/TagKey.java | 20 ++++++++++++-- 29 files changed, 43 insertions(+), 74 deletions(-) diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java index 4ef3d3af0..a0a214920 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java @@ -101,7 +101,6 @@ public class GeneratedKeyType extends SimpleGenerator { .addCode("return $T.create($T.$L, $N);", TypedKey.class, RegistryKey.class, requireNonNull(REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey), "Missing field for " + this.apiRegistryKey), keyParam) .returns(returnType); if (this.publicCreateKeyMethod) { - create.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO remove once not experimental create.addJavadoc(CREATE_JAVADOC, this.apiType, this.registryKey.location().toString()); } return create; @@ -157,8 +156,6 @@ public class GeneratedKeyType extends SimpleGenerator { if (allExperimental) { typeBuilder.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API createMethod.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API - } else { - typeBuilder.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO experimental API } return typeBuilder.addMethod(createMethod.build()).build(); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java index be67e8620..3eef52b64 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.attribute.Attribute; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class AttributeKeys { /** * {@code minecraft:armor} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java index 23e1145e0..bc1f64a8b 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.block.banner.PatternType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class BannerPatternKeys { /** * {@code minecraft:base} @@ -337,7 +335,6 @@ public final class BannerPatternKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.BANNER_PATTERN, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java index bf0c0f6d9..e87e00879 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.block.Biome; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class BiomeKeys { /** * {@code minecraft:badlands} @@ -491,7 +489,6 @@ public final class BiomeKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.BIOME, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java index b71182ed3..f0504b152 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.block.BlockType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class BlockTypeKeys { /** * {@code minecraft:acacia_button} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java index cb3ee5d28..607aa1aee 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.entity.Cat; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class CatVariantKeys { /** * {@code minecraft:all_black} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java index 37476f7b8..47e9afe54 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.damage.DamageType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class DamageTypeKeys { /** * {@code minecraft:arrow} @@ -379,7 +377,6 @@ public final class DamageTypeKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.DAMAGE_TYPE, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java index 33743dd4f..ec7837c8e 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.enchantments.Enchantment; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class EnchantmentKeys { /** * {@code minecraft:aqua_affinity} @@ -330,7 +328,6 @@ public final class EnchantmentKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.ENCHANTMENT, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java index 53b32d989..faf98ef6d 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.Fluid; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class FluidKeys { /** * {@code minecraft:empty} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java index 0a07c0278..b70f508eb 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.entity.Frog; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class FrogVariantKeys { /** * {@code minecraft:cold} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java index 954f46e8d..3477ccb14 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.GameEvent; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class GameEventKeys { /** * {@code minecraft:block_activate} @@ -456,7 +454,6 @@ public final class GameEventKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.GAME_EVENT, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java index 4daa2fac5..391d9b059 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.MusicInstrument; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class InstrumentKeys { /** * {@code minecraft:admire_goat_horn} @@ -92,7 +90,6 @@ public final class InstrumentKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.INSTRUMENT, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java index d13da7a45..75f9a1cc6 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.inventory.ItemType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class ItemTypeKeys { /** * {@code minecraft:acacia_boat} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java index c2992bec9..d86ad9bf2 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.JukeboxSong; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class JukeboxSongKeys { /** * {@code minecraft:11} @@ -169,7 +167,6 @@ public final class JukeboxSongKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.JUKEBOX_SONG, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java index f849e6602..fbf67d675 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.map.MapCursor; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class MapDecorationTypeKeys { /** * {@code minecraft:banner_black} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java index e33724921..06c94936f 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.inventory.MenuType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class MenuTypeKeys { /** * {@code minecraft:anvil} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java index 0ab126f65..58b9c179f 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.potion.PotionEffectType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class MobEffectKeys { /** * {@code minecraft:absorption} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java index 60c7580f0..119dca483 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.Art; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class PaintingVariantKeys { /** * {@code minecraft:alban} @@ -386,7 +384,6 @@ public final class PaintingVariantKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.PAINTING_VARIANT, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java index ece998b1e..9cc0ae85b 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.Sound; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class SoundEventKeys { /** * {@code minecraft:ambient.basalt_deltas.additions} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java index 4a390ebc9..9919f556b 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.generator.structure.Structure; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class StructureKeys { /** * {@code minecraft:ancient_city} @@ -274,7 +272,6 @@ public final class StructureKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.STRUCTURE, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java index 469f355db..79be3249e 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.generator.structure.StructureType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class StructureTypeKeys { /** * {@code minecraft:buried_treasure} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java index 226f1dcad..c9a975907 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.inventory.meta.trim.TrimMaterial; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class TrimMaterialKeys { /** * {@code minecraft:amethyst} @@ -113,7 +111,6 @@ public final class TrimMaterialKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.TRIM_MATERIAL, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java index 67ce5f1b3..a7f2c6341 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.inventory.meta.trim.TrimPattern; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class TrimPatternKeys { /** * {@code minecraft:bolt} @@ -162,7 +160,6 @@ public final class TrimPatternKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.TRIM_PATTERN, key); } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java index 30adcd29e..860e770d4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.entity.Villager; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class VillagerProfessionKeys { /** * {@code minecraft:armorer} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java index 3905a9927..1b9a669d4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.entity.Villager; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class VillagerTypeKeys { /** * {@code minecraft:desert} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java index 6d59b9bf9..7962d0fae 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; import org.bukkit.entity.Wolf; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; /** @@ -25,7 +24,6 @@ import org.jspecify.annotations.NullMarked; }) @GeneratedFrom("1.21.4") @NullMarked -@ApiStatus.Experimental public final class WolfVariantKeys { /** * {@code minecraft:ashen} @@ -99,7 +97,6 @@ public final class WolfVariantKeys { * @param key the value's key in the registry * @return a new typed key */ - @ApiStatus.Experimental public static TypedKey create(final Key key) { return TypedKey.create(RegistryKey.WOLF_VARIANT, key); } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java index ea795de95..0238eb155 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java @@ -1,6 +1,7 @@ package io.papermc.paper.registry; import io.papermc.paper.datacomponent.DataComponentType; +import io.papermc.paper.registry.tag.TagKey; import net.kyori.adventure.key.Key; import net.kyori.adventure.key.KeyPattern; import net.kyori.adventure.key.Keyed; @@ -209,7 +210,6 @@ public sealed interface RegistryKey extends Keyed permits RegistryKeyImpl { * @param key the key of the typed key. * @return the constructed typed key. */ - @ApiStatus.Experimental default TypedKey typedKey(final Key key) { return TypedKey.create(this, key); } @@ -220,8 +220,29 @@ public sealed interface RegistryKey extends Keyed permits RegistryKeyImpl { * @param key the string representation of the key that will be passed to {@link Key#key(String)}. * @return the constructed typed key. */ - @ApiStatus.Experimental - default TypedKey typedKey(final @KeyPattern String key) { + default TypedKey typedKey(@KeyPattern final String key) { return TypedKey.create(this, key); } + + /** + * Constructs a new {@link TagKey} for this registry given the tag key's key. + * + * @param key the key of the typed key. + * @return the constructed tag key. + */ + @ApiStatus.Experimental + default TagKey tagKey(final Key key) { + return TagKey.create(this, key); + } + + /** + * Constructs a new {@link TagKey} for this registry given the tag key's key. + * + * @param key the string representation of the key that will be passed to {@link Key#key(String)}. + * @return the constructed tag key. + */ + @ApiStatus.Experimental + default TagKey tagKey(@KeyPattern final String key) { + return TagKey.create(this, key); + } } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java b/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java index c8f363a24..a1a25c3ca 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/TypedKey.java @@ -11,7 +11,6 @@ import org.jspecify.annotations.NullMarked; * * @param the value type for the registry */ -@ApiStatus.Experimental @NullMarked public sealed interface TypedKey extends Key permits TypedKeyImpl { @@ -39,7 +38,6 @@ public sealed interface TypedKey extends Key permits TypedKeyImpl { * @param value type * @return a new key for the value key and registry key */ - @ApiStatus.Experimental static TypedKey create(final RegistryKey registryKey, final Key key) { return new TypedKeyImpl<>(key, registryKey); } @@ -53,8 +51,7 @@ public sealed interface TypedKey extends Key permits TypedKeyImpl { * @return a new key for the value key and registry key * @see Key#key(String) */ - @ApiStatus.Experimental - static TypedKey create(final RegistryKey registryKey, final @KeyPattern String key) { + static TypedKey create(final RegistryKey registryKey, @KeyPattern final String key) { return create(registryKey, Key.key(key)); } } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/tag/TagKey.java b/paper-api/src/main/java/io/papermc/paper/registry/tag/TagKey.java index f84d95b29..4dda92986 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/tag/TagKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/tag/TagKey.java @@ -1,7 +1,9 @@ package io.papermc.paper.registry.tag; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.TypedKey; import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import net.kyori.adventure.key.Keyed; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; @@ -15,15 +17,29 @@ public sealed interface TagKey extends Keyed permits TagKeyImpl { * Creates a new tag key for a registry. * * @param registryKey the registry for the tag - * @param key the specific key for the tag + * @param key the specific key for the tag + * @param the registry value type * @return a new tag key - * @param the registry value type */ @Contract(value = "_, _ -> new", pure = true) static TagKey create(final RegistryKey registryKey, final Key key) { return new TagKeyImpl<>(registryKey, key); } + /** + * Creates a new tag key for a registry. + * + * @param registryKey the registry for the tag + * @param key the string version of a {@link Key} that will be passed to {@link Key#key(String)} for parsing. + * @param the registry value type + * @return a new tag key + * @see Key#key(String) + */ + @ApiStatus.Experimental + static TagKey create(final RegistryKey registryKey, @KeyPattern final String key) { + return create(registryKey, Key.key(key)); + } + /** * Get the registry key for this tag key. * From 09f1f88f58a03f61092f8636ad780d42db87d8d9 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 18 Feb 2025 01:03:48 +0100 Subject: [PATCH 136/203] Fix getForwards/SidewaysMovement for players (#12140) --- .../java/org/bukkit/entity/LivingEntity.java | 30 ++++++++++++------- .../craftbukkit/entity/CraftPlayer.java | 16 ++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) 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 d21a228bb..5c1a36819 100644 --- a/paper-api/src/main/java/org/bukkit/entity/LivingEntity.java +++ b/paper-api/src/main/java/org/bukkit/entity/LivingEntity.java @@ -1115,10 +1115,13 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource * Retrieves the sideways movement direction of the entity. *

* The returned value ranges from -1 to 1, where: - * - Positive 1 represents movement to the left. - * - Negative 1 represents movement to the right. - *

- * Please note that for entities of type {@link Player}, this value is updated only when riding another entity. + *

    + *
  • Positive 1 represents movement to the left.
  • + *
  • Negative 1 represents movement to the right.
  • + *
+ * + * Please note that for entities of type {@link Player}, this value will only return whole numbers depending + * on what keys are held, see {@link Player#getCurrentInput()}. *

* This method specifically provides information about the entity's sideways movement, whereas {@link #getVelocity()} returns * a vector representing the entity's overall current momentum. @@ -1131,9 +1134,11 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource * Retrieves the upwards movement direction of the entity. *

* The returned value ranges from -1 to 1, where: - * - Positive 1 represents upward movement. - * - Negative 1 represents downward movement. - *

+ *

    + *
  • Positive 1 represents upward movement.
  • + *
  • Negative 1 represents downward movement.
  • + *
+ * * Please note that for entities of type {@link Player}, this value is never updated. *

* This method specifically provides information about the entity's vertical movement, @@ -1148,10 +1153,13 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource * Retrieves the forwards movement direction of the entity. *

* The returned value ranges from -1 to 1, where: - * - Positive 1 represents movement forwards. - * - Negative 1 represents movement backwards. - *

- * Please note that for entities of type {@link Player}, this value is updated only when riding another entity. + *

    + *
  • Positive 1 represents movement forwards.
  • + *
  • Negative 1 represents movement backwards.
  • + *
+ * + * Please note that for entities of type {@link Player}, this value will only return whole numbers depending + * on what keys are held, see {@link Player#getCurrentInput()}. *

* This method specifically provides information about the entity's forward and backward movement, * whereas {@link #getVelocity()} returns a vector representing the entity's overall current momentum. 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 3260f20b6..218a27def 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 @@ -3583,4 +3583,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player { handle.containerMenu.broadcastChanges(); return new PaperPlayerGiveResult(leftovers.build(), drops.build()); } + + @Override + public float getSidewaysMovement() { + final boolean leftMovement = this.getHandle().getLastClientInput().left(); + final boolean rightMovement = this.getHandle().getLastClientInput().right(); + + return leftMovement == rightMovement ? 0 : leftMovement ? 1 : -1; + } + + @Override + public float getForwardsMovement() { + final boolean forwardMovement = this.getHandle().getLastClientInput().forward(); + final boolean backwardMovement = this.getHandle().getLastClientInput().backward(); + + return forwardMovement == backwardMovement ? 0 : forwardMovement ? 1 : -1; + } } From edda0db18b0c9b0304e06fb167b218d1e1cf8d55 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 18 Feb 2025 15:44:52 +0100 Subject: [PATCH 137/203] Fix server crash when no enchantments are present (#12149) --- .../java/io/papermc/paper/util/ItemComponentSanitizer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java b/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java index 15236ed57..74d658d2f 100644 --- a/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java +++ b/paper-server/src/main/java/io/papermc/paper/util/ItemComponentSanitizer.java @@ -27,9 +27,12 @@ public final class ItemComponentSanitizer { */ static final Map, UnaryOperator> SANITIZATION_OVERRIDES = Util.make(ImmutableMap., UnaryOperator>builder(), (map) -> { put(map, DataComponents.LODESTONE_TRACKER, empty(new LodestoneTracker(Optional.empty(), false))); // We need it to be present to keep the glint - put(map, DataComponents.ENCHANTMENTS, empty(dummyEnchantments())); // We need to keep it present to keep the glint - put(map, DataComponents.STORED_ENCHANTMENTS, empty(dummyEnchantments())); // We need to keep it present to keep the glint put(map, DataComponents.POTION_CONTENTS, ItemComponentSanitizer::sanitizePotionContents); // Custom situational serialization + + if (MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).size() > 0) { + put(map, DataComponents.ENCHANTMENTS, empty(dummyEnchantments())); // We need to keep it present to keep the glint + put(map, DataComponents.STORED_ENCHANTMENTS, empty(dummyEnchantments())); // We need to keep it present to keep the glint + } } ).build(); From 5e2a3bc0e24679f94e5a9e3f8594ea03547b5c9c Mon Sep 17 00:00:00 2001 From: Emilia Kond Date: Thu, 20 Feb 2025 11:46:11 +0200 Subject: [PATCH 138/203] Call EntityChangeBlockEvent with correct block when waxing (#12154) --- .../sources/net/minecraft/world/item/HoneycombItem.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch index 9a4c3ee1c..b01647c48 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch @@ -5,7 +5,7 @@ Player player = context.getPlayer(); ItemStack itemInHand = context.getItemInHand(); + // Paper start - EntityChangeBlockEvent -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, blockState)) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, blockState1)) { + if (!player.isCreative()) { + player.containerMenu.sendAllDataToRemote(); + } From ab984a0711e55ac600dfa12a77430799eadd8ac3 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 20 Feb 2025 20:22:46 +0100 Subject: [PATCH 139/203] Always pass event block to damage source (#12158) Always passes the respective block to a damage source when passing a block state. While we could technically use the damageSourcePosition here by, we'd have to translate it back to a block position by subtracting .5 from all its components. Such behaviour however relies on the caller logic's mutation of the damageSourcePosition and will break once this position is not the centre of the block. Passing in the block at the specific callsite is a lot more future proof. --- .../minecraft/world/damagesource/DamageSource.java.patch | 9 +++++++-- .../net/minecraft/world/level/block/BedBlock.java.patch | 2 +- .../world/level/block/RespawnAnchorBlock.java.patch | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch index d530c5c2c..1d3dfd68e 100644 --- a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/damagesource/DamageSource.java +++ b/net/minecraft/world/damagesource/DamageSource.java -@@ -20,6 +_,92 @@ +@@ -20,6 +_,97 @@ private final Entity directEntity; @Nullable private final Vec3 damageSourcePosition; @@ -60,11 +60,16 @@ + return this.fromBlockSnapshot; + } + -+ public DamageSource causingBlockSnapshot(final @Nullable org.bukkit.block.BlockState blockState) { ++ public DamageSource causingBlockSnapshot( ++ final net.minecraft.world.level.LevelAccessor level, ++ final net.minecraft.core.BlockPos pos, ++ final @Nullable org.bukkit.block.BlockState blockState ++ ) { + if (this.eventBlockDamager != null) { + throw new IllegalStateException("Cannot set a block snapshot when an event block damager is already set (report a bug to Paper)"); + } + final DamageSource damageSource = this.copy(); ++ damageSource.eventBlockDamager = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); + damageSource.fromBlockSnapshot = blockState; + return damageSource; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch index 1b12bd9f7..18fb2518e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch @@ -59,7 +59,7 @@ + } + + Vec3 center = pos.getCenter(); -+ level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state ++ level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(level, pos, blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state + return InteractionResult.SUCCESS_SERVER; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch index c66c883b7..63c5b22f8 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch @@ -31,7 +31,7 @@ Vec3 center = pos2.getCenter(); level.explode( - null, level.damageSources().badRespawnPointExplosion(center), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK -+ null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state ++ null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(level, pos2, blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state ); } From 7b4d44f5732422c68aa7f087451efa0aa699b2b6 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Fri, 21 Feb 2025 11:52:04 +0100 Subject: [PATCH 140/203] Revert "Always pass event block to damage source (#12158)" This reverts commit ab984a0711e55ac600dfa12a77430799eadd8ac3. The block damage is null *and has been* null in cases where the block has already been cleared. Consumers are supposed to use the getDamagerBlockState instead. --- .../minecraft/world/damagesource/DamageSource.java.patch | 9 ++------- .../net/minecraft/world/level/block/BedBlock.java.patch | 2 +- .../world/level/block/RespawnAnchorBlock.java.patch | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch index 1d3dfd68e..d530c5c2c 100644 --- a/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/damagesource/DamageSource.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/damagesource/DamageSource.java +++ b/net/minecraft/world/damagesource/DamageSource.java -@@ -20,6 +_,97 @@ +@@ -20,6 +_,92 @@ private final Entity directEntity; @Nullable private final Vec3 damageSourcePosition; @@ -60,16 +60,11 @@ + return this.fromBlockSnapshot; + } + -+ public DamageSource causingBlockSnapshot( -+ final net.minecraft.world.level.LevelAccessor level, -+ final net.minecraft.core.BlockPos pos, -+ final @Nullable org.bukkit.block.BlockState blockState -+ ) { ++ public DamageSource causingBlockSnapshot(final @Nullable org.bukkit.block.BlockState blockState) { + if (this.eventBlockDamager != null) { + throw new IllegalStateException("Cannot set a block snapshot when an event block damager is already set (report a bug to Paper)"); + } + final DamageSource damageSource = this.copy(); -+ damageSource.eventBlockDamager = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); + damageSource.fromBlockSnapshot = blockState; + return damageSource; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch index 18fb2518e..1b12bd9f7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch @@ -59,7 +59,7 @@ + } + + Vec3 center = pos.getCenter(); -+ level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(level, pos, blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state ++ level.explode(null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state + return InteractionResult.SUCCESS_SERVER; + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch index 63c5b22f8..c66c883b7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch @@ -31,7 +31,7 @@ Vec3 center = pos2.getCenter(); level.explode( - null, level.damageSources().badRespawnPointExplosion(center), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK -+ null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(level, pos2, blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state ++ null, level.damageSources().badRespawnPointExplosion(center).causingBlockSnapshot(blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state ); } From e5a8ee849f6ed92f0593bf082bc84e158ee7c5f2 Mon Sep 17 00:00:00 2001 From: bonan Date: Fri, 21 Feb 2025 12:02:32 +0100 Subject: [PATCH 141/203] Hide soul speed particles for vanished players (#12152) Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com> --- .../server/level/ServerLevel.java.patch | 8 ++++---- .../effects/SpawnParticlesEffect.java.patch | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/enchantment/effects/SpawnParticlesEffect.java.patch diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index b6ebadca9..245242b92 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -870,11 +870,11 @@ double zOffset, double speed ) { -+ // CraftBukkit start - visibility api support ++ // Paper start - visibility api support + return this.sendParticlesSource(null, type, overrideLimiter, alwaysShow, posX, posY, posZ, particleCount, xOffset, yOffset, zOffset, speed); + } + public int sendParticlesSource( -+ @javax.annotation.Nullable ServerPlayer sender, ++ @javax.annotation.Nullable Entity sender, + T type, + boolean overrideLimiter, + boolean alwaysShow, @@ -891,7 +891,7 @@ + } + public int sendParticlesSource( + List receivers, -+ @javax.annotation.Nullable ServerPlayer sender, ++ @javax.annotation.Nullable Entity sender, + T type, + boolean overrideLimiter, + boolean alwaysShow, @@ -904,7 +904,7 @@ + double zOffset, + double speed + ) { -+ // CraftBukkit end - visibility api support ++ // Paper end - visibility api support ClientboundLevelParticlesPacket clientboundLevelParticlesPacket = new ClientboundLevelParticlesPacket( type, overrideLimiter, alwaysShow, posX, posY, posZ, (float)xOffset, (float)yOffset, (float)zOffset, (float)speed, particleCount ); diff --git a/paper-server/patches/sources/net/minecraft/world/item/enchantment/effects/SpawnParticlesEffect.java.patch b/paper-server/patches/sources/net/minecraft/world/item/enchantment/effects/SpawnParticlesEffect.java.patch new file mode 100644 index 000000000..68a887a1c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/enchantment/effects/SpawnParticlesEffect.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/item/enchantment/effects/SpawnParticlesEffect.java ++++ b/net/minecraft/world/item/enchantment/effects/SpawnParticlesEffect.java +@@ -58,8 +_,13 @@ + Vec3 knownMovement = entity.getKnownMovement(); + float bbWidth = entity.getBbWidth(); + float bbHeight = entity.getBbHeight(); +- level.sendParticles( ++ // Paper start - Hide soul speed particles for vanished players ++ level.sendParticlesSource( ++ entity, + this.particle, ++ false, ++ false, ++ // Paper end - Hide soul speed particles for vanished players + this.horizontalPosition.getCoordinate(origin.x(), origin.x(), bbWidth, random), + this.verticalPosition.getCoordinate(origin.y(), origin.y() + bbHeight / 2.0F, bbHeight, random), + this.horizontalPosition.getCoordinate(origin.z(), origin.z(), bbWidth, random), From fcb2e815905fbc74d0108549a593873862bc7cd1 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 24 Feb 2025 21:30:56 -0800 Subject: [PATCH 142/203] Clear lastSection on game event listener removal Fixes https://github.com/Tuinity/Moonrise/issues/87 See comments in code --- .../0016-Moonrise-optimisation-patches.patch | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index dbbfc7c13..3c67eed11 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -26735,7 +26735,7 @@ index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7d if (!passengers.equals(this.lastPassengers)) { this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 4a521a37e5fa0250d2cb7b4bc061d309c977e034..fc4a1efaa1f0005237340a236a231d8d3fec8d84 100644 +index 400b56657414177cd76a7b94c426dc7c886aa957..a275b17d0852d9d9bc850614713244e580ae81f1 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -170,7 +170,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; @@ -28372,7 +28372,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 19e4576b4b3be92961e993a8b14c8368789c692e..216482b4bb705520411bdeaa58f6044d05190eb6 100644 +index 994791a83ca6712db3e74ca9aba4bfcd95a0ec6d..1b54cf07616a10d93e9336dbd299ba5f09678a28 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder; @@ -33698,6 +33698,25 @@ index 342c83309b19c64d86e0dd97c1756c96be52772b..423779a2b690f387a4f0bd07b97b50e0 + // Paper end - rewrite chunk system } } +diff --git a/net/minecraft/world/level/gameevent/DynamicGameEventListener.java b/net/minecraft/world/level/gameevent/DynamicGameEventListener.java +index 2b98932e69271571e6e9350c55c82edc858d76f6..c8980c50713e1526c526ed181fb2ad9486bab353 100644 +--- a/net/minecraft/world/level/gameevent/DynamicGameEventListener.java ++++ b/net/minecraft/world/level/gameevent/DynamicGameEventListener.java +@@ -27,6 +27,14 @@ public class DynamicGameEventListener { + + public void remove(ServerLevel level) { + ifChunkExists(level, this.lastSection, listenerRegistry -> listenerRegistry.unregister(this.listener)); ++ // Paper start - rewrite chunk system ++ // We need to unset the last section when removed, otherwise if the same instance is re-added at the same position it ++ // will assume there was no change and fail to re-register. ++ // In vanilla, chunks rarely unload and re-load quickly enough to trigger this issue. However, our chunk system has a ++ // quirk where fast chunk reload cycles will often occur on player login (see PR #22). ++ // So we fix this vanilla oversight as our changes cause it to manifest in bugs much more often (see issue #87). ++ this.lastSection = null; ++ // Paper end - rewrite chunk system + } + + public void move(ServerLevel level) { diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java index 6d61739574155f89511b9adcaf1174841bdc7da7..65728ef17e63d71833677fdcbd5bb90794b4822b 100644 --- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java From 636ae0cd87d303c438db2e5a673fa729c39979ec Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Mon, 24 Feb 2025 21:29:50 -0800 Subject: [PATCH 143/203] Add missing Paper comments to player movement patch --- ...-not-record-movement-for-vehicles-players-unaffect.patch | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch index 0e1eece0f..ad20395cf 100644 --- a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch +++ b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch @@ -11,7 +11,7 @@ a portal in spectator mode and then later switching to creative mode would portal the player. diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 5738709f5fa6fee2ed88ba41a7718c976b780e96..882dbb1276c548316938bbc50f5f7e01f8547ff8 100644 +index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba16a57313b 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -657,7 +657,7 @@ public class ServerGamePacketListenerImpl @@ -19,7 +19,7 @@ index 5738709f5fa6fee2ed88ba41a7718c976b780e96..882dbb1276c548316938bbc50f5f7e01 this.player.serverLevel().getChunkSource().move(this.player); - rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position()); -+ if (!rootVehicle.isSpectator() && rootVehicle.isAffectedByBlocks()) rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position()); ++ if (!rootVehicle.isSpectator() && rootVehicle.isAffectedByBlocks()) rootVehicle.recordMovementThroughBlocks(new Vec3(x, y, z), rootVehicle.position()); // Paper - Do not record movement for vehicles/players unaffected by blocks Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z); this.handlePlayerKnownMovement(vec3); rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3); @@ -28,7 +28,7 @@ index 5738709f5fa6fee2ed88ba41a7718c976b780e96..882dbb1276c548316938bbc50f5f7e01 this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3); this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround()); - this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position()); -+ if (!this.player.isSpectator() && this.player.isAffectedByBlocks()) this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position()); ++ if (!this.player.isSpectator() && this.player.isAffectedByBlocks()) this.player.recordMovementThroughBlocks(new Vec3(x, y, z), this.player.position()); // Paper - Do not record movement for vehicles/players unaffected by blocks this.handlePlayerKnownMovement(vec3); if (flag) { this.player.resetFallDistance(); From 9be4e07a3eca5ca2c03dfdbcf21973e3eae0a759 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Tue, 25 Feb 2025 21:44:42 +0100 Subject: [PATCH 144/203] Pin snapshot dependencies (#12185) Additionally pins configurate-core as a transitive dependency of configurate-yml, as the yaml snapshot depends on a snapshot itself. --- paper-server/build.gradle.kts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index e24fe4a24..84d1b6783 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -137,13 +137,14 @@ dependencies { runtimeOnly(log4jPlugins.output) alsoShade(log4jPlugins.output) - implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") { + implementation("com.velocitypowered:velocity-native:3.4.0-20250222.161222-36") { isTransitive = false } implementation("io.netty:netty-codec-haproxy:4.1.115.Final") // Add support for proxy protocol implementation("org.apache.logging.log4j:log4j-iostreams:2.24.1") implementation("org.ow2.asm:asm-commons:9.7.1") - implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") + implementation("org.spongepowered:configurate-yaml:4.2.0-20250225.064233-199") + implementation("org.spongepowered:configurate-core:4.2.0-20250225.064233-204") // Pinned dependency of above pinned yaml snapshot. implementation("commons-lang:commons-lang:2.6") runtimeOnly("org.xerial:sqlite-jdbc:3.47.0.0") runtimeOnly("com.mysql:mysql-connector-j:9.1.0") @@ -173,7 +174,7 @@ dependencies { // Spark implementation("me.lucko:spark-api:0.1-20240720.200737-2") - implementation("me.lucko:spark-paper:1.10.119-SNAPSHOT") + implementation("me.lucko:spark-paper:1.10.119-20241121.092015-1") } tasks.jar { From f12d33f04ee42e1e08b7d3050f30185434db0a88 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Tue, 25 Feb 2025 21:44:51 +0100 Subject: [PATCH 145/203] Track codec writing --- .../network/FriendlyByteBuf.java.patch | 9 +++- .../network/codec/ByteBufCodecs.java.patch | 51 +++++++++++++++++++ ...ServerboundContainerClickPacket.java.patch | 20 ++++++++ ...rboundSetCreativeModeSlotPacket.java.patch | 11 ++++ .../world/effect/MobEffectInstance.java.patch | 18 +++++++ .../item/component/BundleContents.java.patch | 8 +++ .../component/ChargedProjectiles.java.patch | 10 ++++ .../ItemContainerContents.java.patch | 10 ++++ .../item/component/UseRemainder.java.patch | 11 ++++ 9 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/component/ChargedProjectiles.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/component/ItemContainerContents.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/component/UseRemainder.java.patch diff --git a/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch b/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch index f06b6bc4a..e28fd7bb0 100644 --- a/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/FriendlyByteBuf.java +++ b/net/minecraft/network/FriendlyByteBuf.java -@@ -70,6 +_,7 @@ +@@ -70,14 +_,20 @@ public class FriendlyByteBuf extends ByteBuf { public static final int DEFAULT_NBT_QUOTA = 2097152; private final ByteBuf source; @@ -8,8 +8,13 @@ public static final short MAX_STRING_LENGTH = 32767; public static final int MAX_COMPONENT_STRING_LENGTH = 262144; private static final int PUBLIC_KEY_SIZE = 256; -@@ -78,6 +_,7 @@ + private static final int MAX_PUBLIC_KEY_HEADER_SIZE = 256; + private static final int MAX_PUBLIC_KEY_LENGTH = 512; private static final Gson GSON = new Gson(); ++ // Paper start - Track codec depth ++ public boolean trackCodecDepth; ++ public byte codecDepth; ++ // Paper end - Track codec depth public FriendlyByteBuf(ByteBuf source) { + this.adventure$locale = PacketEncoder.ADVENTURE_LOCALE.get(); // Paper - track player's locale for server-side translations diff --git a/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch b/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch new file mode 100644 index 000000000..129aa1daf --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/network/codec/ByteBufCodecs.java ++++ b/net/minecraft/network/codec/ByteBufCodecs.java +@@ -378,6 +_,48 @@ + }; + } + ++ // Paper start - Track codec depth ++ static StreamCodec trackDepth(final StreamCodec codec) { ++ return new StreamCodec<>() { ++ @Override ++ public V decode(B buffer) { ++ buffer.trackCodecDepth = true; ++ try { ++ return codec.decode(buffer); ++ } finally { ++ buffer.trackCodecDepth = false; ++ buffer.codecDepth = 0; ++ } ++ } ++ ++ @Override ++ public void encode(B buffer, V value) { ++ codec.encode(buffer, value); ++ } ++ }; ++ } ++ ++ static StreamCodec increaseDepth(final StreamCodec codec) { ++ return new StreamCodec<>() { ++ @Override ++ public V decode(B buffer) { ++ if (!buffer.trackCodecDepth) { ++ return codec.decode(buffer); ++ } ++ if (++buffer.codecDepth > 64) { ++ throw new DecoderException("Too deep"); ++ } ++ return codec.decode(buffer); ++ } ++ ++ @Override ++ public void encode(B buffer, V value) { ++ codec.encode(buffer, value); ++ } ++ }; ++ } ++ // Paper end - Track codec depth ++ + static StreamCodec> optional(final StreamCodec codec) { + return new StreamCodec>() { + @Override diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java.patch new file mode 100644 index 000000000..05b6fc07c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java ++++ b/net/minecraft/network/protocol/game/ServerboundContainerClickPacket.java +@@ -17,7 +_,7 @@ + ); + private static final int MAX_SLOT_COUNT = 128; + private static final StreamCodec> SLOTS_STREAM_CODEC = ByteBufCodecs.map( +- Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC, 128 ++ Int2ObjectOpenHashMap::new, ByteBufCodecs.SHORT.map(Short::intValue, Integer::shortValue), ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth), 128 // Paper - Track codec depth + ); + private final int containerId; + private final int stateId; +@@ -46,7 +_,7 @@ + this.buttonNum = buffer.readByte(); + this.clickType = buffer.readEnum(ClickType.class); + this.changedSlots = Int2ObjectMaps.unmodifiable(SLOTS_STREAM_CODEC.decode(buffer)); +- this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer); ++ this.carriedItem = ItemStack.OPTIONAL_STREAM_CODEC.apply(ByteBufCodecs::trackDepth).decode(buffer); // Paper - Track codec depth + } + + private void write(RegistryFriendlyByteBuf buffer) { diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java.patch new file mode 100644 index 000000000..1ebb632f6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java ++++ b/net/minecraft/network/protocol/game/ServerboundSetCreativeModeSlotPacket.java +@@ -11,7 +_,7 @@ + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.SHORT, + ServerboundSetCreativeModeSlotPacket::slotNum, +- ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC), ++ ItemStack.validatedStreamCodec(ItemStack.OPTIONAL_STREAM_CODEC).apply(ByteBufCodecs::trackDepth), // Paper - Track codec depth + ServerboundSetCreativeModeSlotPacket::itemStack, + ServerboundSetCreativeModeSlotPacket::new + ); diff --git a/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch b/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch index 7cdda27b0..25df61219 100644 --- a/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/effect/MobEffectInstance.java.patch @@ -8,3 +8,21 @@ && !this.effect.value().applyEffectTick(serverLevel, entity, this.amplifier)) { entity.removeEffect(this.effect); } +@@ -408,7 +_,7 @@ + .apply(instance, MobEffectInstance.Details::create) + ) + ); +- public static final StreamCodec STREAM_CODEC = StreamCodec.recursive( ++ public static final StreamCodec STREAM_CODEC = StreamCodec.recursive( // Paper - Track codec depth + codec -> StreamCodec.composite( + ByteBufCodecs.VAR_INT, + MobEffectInstance.Details::amplifier, +@@ -420,7 +_,7 @@ + MobEffectInstance.Details::showParticles, + ByteBufCodecs.BOOL, + MobEffectInstance.Details::showIcon, +- codec.apply(ByteBufCodecs::optional), ++ codec.apply(ByteBufCodecs::increaseDepth).apply(ByteBufCodecs::optional), // Paper - Track codec depth + MobEffectInstance.Details::hiddenEffect, + MobEffectInstance.Details::new + ) diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch index cc4795690..c5caf800f 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/component/BundleContents.java.patch @@ -1,5 +1,13 @@ --- a/net/minecraft/world/item/component/BundleContents.java +++ b/net/minecraft/world/item/component/BundleContents.java +@@ -25,6 +_,7 @@ + .flatXmap(BundleContents::checkAndCreate, bundleContents -> DataResult.success(bundleContents.items)); + public static final StreamCodec STREAM_CODEC = ItemStack.STREAM_CODEC + .apply(ByteBufCodecs.list()) ++ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth + .map(BundleContents::new, contents -> contents.items); + private static final Fraction BUNDLE_IN_BUNDLE_WEIGHT = Fraction.getFraction(1, 16); + private static final int NO_STACK_INDEX = -1; @@ -76,6 +_,12 @@ return !stack.isEmpty() && stack.getItem().canFitInsideContainerItems(); } diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/ChargedProjectiles.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/ChargedProjectiles.java.patch new file mode 100644 index 000000000..37b441949 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/component/ChargedProjectiles.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/item/component/ChargedProjectiles.java ++++ b/net/minecraft/world/item/component/ChargedProjectiles.java +@@ -16,6 +_,7 @@ + .xmap(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items); + public static final StreamCodec STREAM_CODEC = ItemStack.STREAM_CODEC + .apply(ByteBufCodecs.list()) ++ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth + .map(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items); + private final List items; + diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/ItemContainerContents.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/ItemContainerContents.java.patch new file mode 100644 index 000000000..825d0f014 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/component/ItemContainerContents.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/item/component/ItemContainerContents.java ++++ b/net/minecraft/world/item/component/ItemContainerContents.java +@@ -22,6 +_,7 @@ + .xmap(ItemContainerContents::fromSlots, ItemContainerContents::asSlots); + public static final StreamCodec STREAM_CODEC = ItemStack.OPTIONAL_STREAM_CODEC + .apply(ByteBufCodecs.list(256)) ++ .apply(ByteBufCodecs::increaseDepth) // Paper - Track codec depth + .map(ItemContainerContents::new, contents -> contents.items); + public final NonNullList items; + private final int hashCode; diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/UseRemainder.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/UseRemainder.java.patch new file mode 100644 index 000000000..a10f28000 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/component/UseRemainder.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/item/component/UseRemainder.java ++++ b/net/minecraft/world/item/component/UseRemainder.java +@@ -8,7 +_,7 @@ + public record UseRemainder(ItemStack convertInto) { + public static final Codec CODEC = ItemStack.CODEC.xmap(UseRemainder::new, UseRemainder::convertInto); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( +- ItemStack.STREAM_CODEC, UseRemainder::convertInto, UseRemainder::new ++ ItemStack.STREAM_CODEC.apply(net.minecraft.network.codec.ByteBufCodecs::increaseDepth), UseRemainder::convertInto, UseRemainder::new // Paper - Track codec depth + ); + + public ItemStack convertIntoRemainder(ItemStack stack, int count, boolean hasInfiniteMaterials, UseRemainder.OnExtraCreatedRemainder onExtraCreated) { From 1d9b39942734c1c360653f6a541ebe058ff48ec1 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:45:18 +0100 Subject: [PATCH 146/203] Add config option for failed beehive release cooldowns (#12186) --- .../world/level/block/entity/BeehiveBlockEntity.java.patch | 2 +- .../io/papermc/paper/configuration/WorldConfiguration.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch index 7950dedc6..79355e0ee 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch @@ -163,7 +163,7 @@ iterator.remove(); } + // Paper start - Fix bees aging inside; use exitTickCounter to keep actual bee life -+ else { ++ else if (level.paperConfig().entities.behavior.cooldownFailedBeehiveReleases) { + beeData.exitTickCounter = beeData.occupant.minTicksInHive / 2; + } + // Paper end - Fix bees aging inside; use exitTickCounter to keep actual bee life diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java index d7c9acaff..d193330bf 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java @@ -327,6 +327,9 @@ public class WorldConfiguration extends ConfigurationPart { public int day = 5; } } + + @Comment("Adds a cooldown to bees being released after a failed release, which can occur if the hive is blocked or it being night.") + public boolean cooldownFailedBeehiveReleases = true; } public TrackingRangeY trackingRangeY; From 5f2ee83ed40c9ef1af2e8d2e275d85143cb7b17c Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:45:33 +0100 Subject: [PATCH 147/203] Fix first execution of async delayed/repeating tasks being sync (#12166) --- .../paper/threadedregions/scheduler/FoliaAsyncScheduler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaAsyncScheduler.java b/paper-server/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaAsyncScheduler.java index 374abffb9..c03180da9 100644 --- a/paper-server/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaAsyncScheduler.java +++ b/paper-server/src/main/java/io/papermc/paper/threadedregions/scheduler/FoliaAsyncScheduler.java @@ -181,7 +181,7 @@ public final class FoliaAsyncScheduler implements AsyncScheduler { private void setDelay(final ScheduledFuture delay) { this.delay = delay; - this.state = STATE_SCHEDULED_EXECUTOR; + this.state = delay == null ? STATE_SCHEDULED_EXECUTOR : STATE_ON_TIMER; } @Override From b00875f86d155741d7a185fe107564203f3a9bca Mon Sep 17 00:00:00 2001 From: Glicz <67753196+GliczDev@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:02:48 +0100 Subject: [PATCH 148/203] Add a method on Registry to get the size (#12182) --- .../src/main/java/org/bukkit/Registry.java | 23 +++++++++++++++++++ .../registry/legacy/DelayedRegistry.java | 5 ++++ .../org/bukkit/craftbukkit/CraftRegistry.java | 5 ++++ 3 files changed, 33 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index 8f96e193c..09d999877 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -3,6 +3,7 @@ package org.bukkit; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; import io.papermc.paper.datacomponent.DataComponentType; import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; @@ -297,6 +298,11 @@ public interface Registry extends Iterable { return MemoryKey.values().iterator(); } + @Override + public int size() { + return MemoryKey.values().size(); + } + @Override public @Nullable MemoryKey get(final NamespacedKey key) { return MemoryKey.getByKey(key); @@ -536,6 +542,13 @@ public interface Registry extends Iterable { return (namespacedKey != null) ? this.get(namespacedKey) : null; } + /** + * Gets the size of the registry. + * + * @return the size of the registry + */ + int size(); + @ApiStatus.Internal class SimpleRegistry & Keyed> extends NotARegistry { // Paper - remove final @@ -564,6 +577,11 @@ public interface Registry extends Iterable { return this.map.get(key); } + @Override + public int size() { + return map.size(); + } + @Override public Iterator iterator() { return this.map.values().iterator(); @@ -584,6 +602,11 @@ public interface Registry extends Iterable { return StreamSupport.stream(this.spliterator(), false); } + @Override + public int size() { + return Iterables.size(this); + } + @Override public NamespacedKey getKey(final A value) { return value.getKey(); diff --git a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java index 527fbbbbe..8147fe865 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/legacy/DelayedRegistry.java @@ -49,6 +49,11 @@ public final class DelayedRegistry> imple return this.delegate().stream(); } + @Override + public int size() { + return this.delegate().size(); + } + @Override public @Nullable NamespacedKey getKey(final T value) { return this.delegate().getKey(value); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index 2de46d741..f8c83e4a9 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -233,6 +233,11 @@ public class CraftRegistry implements Registry { return this.minecraftRegistry.keySet().stream().map(minecraftKey -> this.get(CraftNamespacedKey.fromMinecraft(minecraftKey))); } + @Override + public int size() { + return this.minecraftRegistry.size(); + } + @Override public Iterator iterator() { return this.stream().iterator(); From ca2610904b2de9e22c4c88c03d43e48be5dfe85b Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:03:14 +0100 Subject: [PATCH 149/203] Don't process empty rcon commands (#12188) --- .../net/minecraft/server/dedicated/DedicatedServer.java.patch | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch index a71879d2e..1b3175021 100644 --- a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -361,7 +361,7 @@ } @Override -@@ -515,14 +_,52 @@ +@@ -515,14 +_,54 @@ @Override public String getPluginNames() { @@ -402,6 +402,8 @@ + } + + public String runCommand(RconConsoleSource rconConsoleSource, String s) { ++ if (s.isBlank()) return ""; // Paper - Do not process empty rcon commands ++ + rconConsoleSource.prepareForCommand(); + this.executeBlocking(() -> { + CommandSourceStack wrapper = rconConsoleSource.createCommandSourceStack(); From a501c4591880e4238a15834c7e0aeefc0a219341 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:03:38 +0100 Subject: [PATCH 150/203] Deprecate server config getters (#12189) --- .../src/main/java/org/bukkit/Bukkit.java | 11 +++++ .../src/main/java/org/bukkit/Server.java | 40 +++++++++++++++++++ .../org/bukkit/craftbukkit/CraftServer.java | 7 +++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/bukkit/Bukkit.java b/paper-api/src/main/java/org/bukkit/Bukkit.java index 9764489c0..a371da9d1 100644 --- a/paper-api/src/main/java/org/bukkit/Bukkit.java +++ b/paper-api/src/main/java/org/bukkit/Bukkit.java @@ -2980,8 +2980,19 @@ public final class Bukkit { } // Paper end - Folia region threading API + /** + * @deprecated All methods on this class have been deprecated, see the individual methods for replacements. + */ + @Deprecated(since = "1.21.4", forRemoval = true) @NotNull public static Server.Spigot spigot() { return server.spigot(); } + + /** + * Restarts the server. If the server administrator has not configured restarting, the server will stop. + */ + public static void restart() { + server.restart(); + } } diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index fa6f9d505..b136c30b9 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -2309,24 +2309,52 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Spigot start public class Spigot { + /** + * @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. + * + * @return The server's spigot config. + */ + @Deprecated(since = "1.21.4", forRemoval = true) @NotNull public org.bukkit.configuration.file.YamlConfiguration getConfig() { throw new UnsupportedOperationException("Not supported yet."); } + /** + * @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. + * + * @return The server's bukkit config. + */ // Paper start + @Deprecated(since = "1.21.4", forRemoval = true) @NotNull public org.bukkit.configuration.file.YamlConfiguration getBukkitConfig() { throw new UnsupportedOperationException( "Not supported yet." ); } + /** + * @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. + * + * @return The server's spigot config. + */ + @Deprecated(since = "1.21.4", forRemoval = true) @NotNull public org.bukkit.configuration.file.YamlConfiguration getSpigotConfig() { throw new UnsupportedOperationException("Not supported yet."); } + /** + * @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. + * + * @return The server's paper config. + */ + @Deprecated(since = "1.21.4", forRemoval = true) @NotNull public org.bukkit.configuration.file.YamlConfiguration getPaperConfig() { @@ -2358,16 +2386,28 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi /** * Restart the server. If the server administrator has not configured restarting, the server will stop. + * + * @deprecated Use {@link Server#restart()} instead. */ + @Deprecated(since = "1.21.4", forRemoval = true) public void restart() { throw new UnsupportedOperationException("Not supported yet."); } } + /** + * @deprecated All methods on this class have been deprecated, see the individual methods for replacements. + */ + @Deprecated(since = "1.21.4", forRemoval = true) @NotNull Spigot spigot(); // Spigot end + /** + * Restarts the server. If the server administrator has not configured restarting, the server will stop. + */ + void restart(); + void reloadPermissions(); // Paper boolean reloadCommandAliases(); // Paper 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 59eddee7e..a0a1ed48f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -3053,7 +3053,7 @@ public final class CraftServer implements Server { @Override public void restart() { - org.spigotmc.RestartCommand.restart(); + CraftServer.this.restart(); } @Override @@ -3077,6 +3077,11 @@ public final class CraftServer implements Server { } // Spigot end + @Override + public void restart() { + org.spigotmc.RestartCommand.restart(); + } + @Override public double[] getTPS() { return new double[] { From 7f3d3591dea7bdbd90da0fdcd5f410084e79a0fd Mon Sep 17 00:00:00 2001 From: _Novit_ <90355736+novitpw@users.noreply.github.com> Date: Wed, 26 Feb 2025 00:06:20 +0300 Subject: [PATCH 151/203] Use MiniMessage#deserialize(String, Pointered) in sendRichMessage for send messages (#12177) --- paper-api/src/main/java/org/bukkit/Server.java | 4 ++-- paper-api/src/main/java/org/bukkit/command/CommandSender.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index b136c30b9..d7ebfcfc6 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -422,7 +422,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @param message MiniMessage content */ default void sendRichMessage(final @NotNull String message) { - this.sendMessage(MiniMessage.miniMessage().deserialize(message)); + this.sendMessage(MiniMessage.miniMessage().deserialize(message, this)); } /** @@ -435,7 +435,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @param resolvers resolvers to use */ default void sendRichMessage(final @NotNull String message, final @NotNull TagResolver... resolvers) { - this.sendMessage(MiniMessage.miniMessage().deserialize(message, resolvers)); + this.sendMessage(MiniMessage.miniMessage().deserialize(message, this, resolvers)); } /** diff --git a/paper-api/src/main/java/org/bukkit/command/CommandSender.java b/paper-api/src/main/java/org/bukkit/command/CommandSender.java index 04e7cd0e4..1fd0f5f4d 100644 --- a/paper-api/src/main/java/org/bukkit/command/CommandSender.java +++ b/paper-api/src/main/java/org/bukkit/command/CommandSender.java @@ -147,7 +147,7 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe * @param message MiniMessage content */ default void sendRichMessage(final @NotNull String message) { - this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message)); + this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, this)); } /** @@ -160,7 +160,7 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe * @param resolvers resolvers to use */ default void sendRichMessage(final @NotNull String message, final net.kyori.adventure.text.minimessage.tag.resolver.@NotNull TagResolver... resolvers) { - this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, resolvers)); + this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message, this, resolvers)); } /** From 9b9f046f41d56fe879f1ba86002cec2ebf1c5c51 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:14:21 +0100 Subject: [PATCH 152/203] Remove broken code (#12171) --- .../entity/projectile/ThrownPotion.java.patch | 132 ++++++------------ 1 file changed, 44 insertions(+), 88 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownPotion.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownPotion.java.patch index 0fbeafb10..8c092de10 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownPotion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownPotion.java.patch @@ -1,14 +1,6 @@ --- a/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/net/minecraft/world/entity/projectile/ThrownPotion.java -@@ -9,6 +_,7 @@ - import net.minecraft.core.Holder; - import net.minecraft.core.component.DataComponents; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.tags.BlockTags; - import net.minecraft.world.damagesource.DamageSource; - import net.minecraft.world.effect.MobEffect; -@@ -82,51 +_,87 @@ +@@ -82,51 +_,86 @@ @Override protected void onHit(HitResult result) { super.onHit(result); @@ -28,12 +20,12 @@ + } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply if (this.isLingering()) { - this.makeAreaOfEffectCloud(potionContents); -+ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass MovingObjectPosition // Paper ++ showParticles = this.makeAreaOfEffectCloud(potionContents, result); // CraftBukkit - Pass HitResult // Paper } else { - this.applySplash( - serverLevel, potionContents.getAllEffects(), result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null -+ showParticles = this.applySplash( -+ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API ++ showParticles = this.applySplash( // Paper - Fix potions splash events ++ serverLevel, potionContents.getAllEffects(), result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result // CraftBukkit - Pass HitResult // Paper - More projectile API ); } } @@ -48,7 +40,7 @@ } - private void applyWater(ServerLevel level) { -+ private static final Predicate APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events ++ private static final Predicate APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events + + private boolean applyWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0); @@ -67,20 +59,19 @@ if (d < 16.0) { if (livingEntity.isSensitiveToWater()) { - livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F); -+ affected.put(livingEntity.getBukkitLivingEntity(), 1.0); -+ // livingEntity.hurtServer(level, this.damageSources().indirectMagic(this, this.getOwner()), 1.0F); ++ affected.put(livingEntity.getBukkitLivingEntity(), 1.0); // Paper - Fix potions splash events } if (livingEntity.isOnFire() && livingEntity.isAlive()) { - livingEntity.extinguishFire(); -+ extinguish.add(livingEntity.getBukkitLivingEntity()); -+ // livingEntity.extinguishFire(); ++ extinguish.add(livingEntity.getBukkitLivingEntity()); // Paper - Fix potions splash events } } } - for (Axolotl axolotl : this.level().getEntitiesOfClass(Axolotl.class, aabb)) { - axolotl.rehydrate(); ++ // Paper start - Fix potions splash events + io.papermc.paper.event.entity.WaterBottleSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callWaterBottleSplashEvent( + this, result, affected, rehydrate, extinguish + ); @@ -102,14 +93,14 @@ } - private void applySplash(ServerLevel level, Iterable effects, @Nullable Entity entity) { -+ private boolean applySplash(ServerLevel level, Iterable effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API ++ private boolean applySplash(ServerLevel level, Iterable effects, @Nullable Entity entity, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - Fix potions splash events & More projectile API AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0); List entitiesOfClass = level.getEntitiesOfClass(LivingEntity.class, aabb); + java.util.Map affected = new java.util.HashMap<>(); // CraftBukkit if (!entitiesOfClass.isEmpty()) { Entity effectSource = this.getEffectSource(); -@@ -135,33 +_,57 @@ +@@ -135,12 +_,31 @@ double d = this.distanceToSqr(livingEntity); if (d < 16.0) { double d1; @@ -120,69 +111,45 @@ d1 = 1.0 - Math.sqrt(d) / 4.0; } -- for (MobEffectInstance mobEffectInstance : effects) { -- Holder effect = mobEffectInstance.getEffect(); -- if (effect.value().isInstantenous()) { -- effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1); -- } else { -- int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5)); -- MobEffectInstance mobEffectInstance1 = new MobEffectInstance( -- effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible() -- ); -- if (!mobEffectInstance1.endsWithin(20)) { -- livingEntity.addEffect(mobEffectInstance1, effectSource); -- } -- } -- } -- } -- } -- } -- } + affected.put(livingEntity.getBukkitLivingEntity(), d1); ++ // CraftBukkit start + } + } + } + } + org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, result, affected); -+ if (!event.isCancelled() && entitiesOfClass != null && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process ++ if (!event.isCancelled() && !entitiesOfClass.isEmpty()) { // do not process effects if there are no effects to process + Entity effectSource = this.getEffectSource(); + for (org.bukkit.entity.LivingEntity victim : event.getAffectedEntities()) { + if (!(victim instanceof org.bukkit.craftbukkit.entity.CraftLivingEntity craftLivingEntity)) { + continue; + } -+ net.minecraft.world.entity.LivingEntity livingEntity = craftLivingEntity.getHandle(); ++ LivingEntity livingEntity = craftLivingEntity.getHandle(); + double d1 = event.getIntensity(victim); -+ // CraftBukkit end -+ for (MobEffectInstance mobEffectInstance : effects) { -+ Holder effect = mobEffectInstance.getEffect(); -+ // CraftBukkit start - Abide by PVP settings - for players only! -+ if (!this.level().pvpMode && this.getOwner() instanceof ServerPlayer && livingEntity instanceof ServerPlayer && livingEntity != this.getOwner()) { -+ MobEffect mobEffect = effect.value(); -+ if (mobEffect == net.minecraft.world.effect.MobEffects.MOVEMENT_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.DIG_SLOWDOWN || mobEffect == net.minecraft.world.effect.MobEffects.HARM || mobEffect == net.minecraft.world.effect.MobEffects.BLINDNESS -+ || mobEffect == net.minecraft.world.effect.MobEffects.HUNGER || mobEffect == net.minecraft.world.effect.MobEffects.WEAKNESS || mobEffect == net.minecraft.world.effect.MobEffects.POISON) { -+ continue; -+ } -+ } ++ { ++ { + // CraftBukkit end -+ if (effect.value().isInstantenous()) { -+ effect.value().applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), d1); -+ } else { -+ int i = mobEffectInstance.mapDuration(i1 -> (int)(d1 * i1 + 0.5)); -+ MobEffectInstance mobEffectInstance1 = new MobEffectInstance( -+ effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible() -+ ); -+ if (!mobEffectInstance1.endsWithin(20)) { -+ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit -+ } -+ } -+ } -+ } -+ } + for (MobEffectInstance mobEffectInstance : effects) { + Holder effect = mobEffectInstance.getEffect(); + if (effect.value().isInstantenous()) { +@@ -151,7 +_,7 @@ + effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible() + ); + if (!mobEffectInstance1.endsWithin(20)) { +- livingEntity.addEffect(mobEffectInstance1, effectSource); ++ livingEntity.addEffect(mobEffectInstance1, effectSource, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_SPLASH); // CraftBukkit + } + } + } +@@ -159,9 +_,10 @@ + } + } + } + return !event.isCancelled(); // Paper - Fix potions splash events } - private void makeAreaOfEffectCloud(PotionContents potionContents) { -+ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API ++ private boolean makeAreaOfEffectCloud(PotionContents potionContents, @Nullable HitResult result) { // CraftBukkit - Pass HitResult // Paper - More projectile API AreaEffectCloud areaEffectCloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ()); if (this.getOwner() instanceof LivingEntity livingEntity) { areaEffectCloud.setOwner(livingEntity); @@ -197,41 +164,30 @@ + if (!(event.isCancelled() || areaEffectCloud.isRemoved() || (!event.allowsEmptyCreation() && (noEffects && !areaEffectCloud.potionContents.hasEffects())))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling + this.level().addFreshEntity(areaEffectCloud); + } else { -+ areaEffectCloud.discard(null); // CraftBukkit - add Bukkit remove cause ++ areaEffectCloud.discard(null); // add Bukkit remove cause + } + // CraftBukkit end + return !event.isCancelled(); // Paper - Fix potions splash events } public boolean isLingering() { -@@ -182,13 +_,25 @@ +@@ -182,13 +_,19 @@ private void dowseFire(BlockPos pos) { BlockState blockState = this.level().getBlockState(pos); if (blockState.is(BlockTags.FIRE)) { -- this.level().destroyBlock(pos, false, this); -+ // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state -+ this.level().destroyBlock(pos, false, this); -+ } -+ // CraftBukkit end + this.level().destroyBlock(pos, false, this); ++ } // CraftBukkit } else if (AbstractCandleBlock.isLit(blockState)) { -- AbstractCandleBlock.extinguish(null, blockState, this.level(), pos); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, false))) { -+ AbstractCandleBlock.extinguish(null, blockState, this.level(), pos); -+ } -+ // CraftBukkit end ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(AbstractCandleBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit + AbstractCandleBlock.extinguish(null, blockState, this.level(), pos); ++ } // CraftBukkit } else if (CampfireBlock.isLitCampfire(blockState)) { -- this.level().levelEvent(null, 1009, pos, 0); -- CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState); -- this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false))); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, false))) { -+ this.level().levelEvent(null, 1009, pos, 0); -+ CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState); -+ this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, false)); -+ } -+ // CraftBukkit end ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)))) { // CraftBukkit + this.level().levelEvent(null, 1009, pos, 0); + CampfireBlock.dowse(this.getOwner(), this.level(), pos, blockState); + this.level().setBlockAndUpdate(pos, blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false))); ++ } // CraftBukkit } } From fc56c728c0790a6d493ac380c313c940e1100615 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:23:47 -0300 Subject: [PATCH 153/203] Add methods for Creaking (#12094) --- .../main/java/org/bukkit/entity/Creaking.java | 35 +++++++++++++++++++ .../craftbukkit/entity/CraftCreaking.java | 32 ++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/bukkit/entity/Creaking.java b/paper-api/src/main/java/org/bukkit/entity/Creaking.java index 2e85cc40e..4d02eb150 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Creaking.java +++ b/paper-api/src/main/java/org/bukkit/entity/Creaking.java @@ -1,8 +1,43 @@ package org.bukkit.entity; +import org.bukkit.Location; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + /** * Represents a Creaking. */ +@NullMarked public interface Creaking extends Monster { + /** + * Gets the home location for this creaking (where its {@link org.bukkit.block.CreakingHeart} could be found). + * + * @return the location of the home if available, null otherwise + */ + @Nullable + Location getHome(); + + /** + * Activates this creaking to target and follow a player. + * + * @param player the target + */ + void activate(final Player player); + + /** + * Deactivates the creaking, clearing its current attack target and + * marking it as inactive. + */ + void deactivate(); + + /** + * Returns if this creaking is currently active and hunting. + * + * @see #activate(Player) + * + * @return true if active + */ + boolean isActive(); + } 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 267f3c850..d9b7ad7f3 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 @@ -1,11 +1,19 @@ package org.bukkit.craftbukkit.entity; +import com.google.common.base.Preconditions; +import net.minecraft.Optionull; import net.minecraft.world.entity.monster.creaking.Creaking; +import org.bukkit.Location; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.util.CraftLocation; +import org.bukkit.entity.Player; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +@NullMarked public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Creaking { - public CraftCreaking(CraftServer server, Creaking entity) { + public CraftCreaking(final CraftServer server, final Creaking entity) { super(server, entity); } @@ -14,6 +22,28 @@ public class CraftCreaking extends CraftMonster implements org.bukkit.entity.Cre return (Creaking) this.entity; } + @Nullable + @Override + public Location getHome() { + return Optionull.map(this.getHandle().getHomePos(), pos -> CraftLocation.toBukkit(pos, this.getHandle().level())); + } + + @Override + public void activate(final Player player) { + Preconditions.checkArgument(player != null, "player cannot be null"); + this.getHandle().activate(((CraftPlayer) player).getHandle()); + } + + @Override + public void deactivate() { + this.getHandle().deactivate(); + } + + @Override + public boolean isActive() { + return this.getHandle().isActive(); + } + @Override public String toString() { return "CraftCreaking"; From f63dbeafde535ae10bc5879e841b943df6731cfd Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:33:35 +0100 Subject: [PATCH 154/203] Fix cancelled HangingPlaceEvent inventory desync (#12161) --- .../net/minecraft/world/item/HangingEntityItem.java.patch | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch index ae35e0397..c1d7700dc 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/HangingEntityItem.java +++ b/net/minecraft/world/item/HangingEntityItem.java -@@ -66,6 +_,19 @@ +@@ -66,6 +_,20 @@ if (hangingEntity.survives()) { if (!level.isClientSide) { @@ -14,6 +14,7 @@ + level.getCraftServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { ++ if (player != null) player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync + return InteractionResult.FAIL; + } + // CraftBukkit end From 9421f223724576accdb94041ec3e4772d4acd670 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Wed, 26 Feb 2025 04:12:23 -0800 Subject: [PATCH 155/203] Make CustomArgumentType use parse(reader,source) (#12191) --- .../brigadier/argument/VanillaArgumentProviderImpl.java | 5 +++++ .../brigadier/argument/WrappedArgumentCommandNode.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) 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 3cfe31942..b41d4a1fc 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 @@ -366,6 +366,11 @@ public class VanillaArgumentProviderImpl implements VanillaArgumentProvider { return this.converter.convert(this.nmsBase.parse(reader)); } + @Override + public P parse(final StringReader reader, final S source) throws CommandSyntaxException { + return this.converter.convert(this.nmsBase.parse(reader, source)); + } + @Override public CompletableFuture listSuggestions(final CommandContext context, final SuggestionsBuilder builder) { return this.nmsBase.listSuggestions(context, builder); diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java index c59bbd90f..a66d90709 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/argument/WrappedArgumentCommandNode.java @@ -46,7 +46,7 @@ public class WrappedArgumentCommandNode extends ArgumentCommandNode contextBuilder) throws CommandSyntaxException { final int start = reader.getCursor(); - final API result = this.pureArgumentType.parse(reader); // Use the api argument parser + final API result = this.pureArgumentType.parse(reader, contextBuilder.getSource()); // Use the api argument parser final ParsedArgument parsed = new ParsedArgument<>(start, reader.getCursor(), result); // Return an API parsed argument instead. contextBuilder.withArgument(this.getName(), parsed); From 0a6e7435b319d658e60d437f092481f51e7f7ece Mon Sep 17 00:00:00 2001 From: okx-code Date: Wed, 26 Feb 2025 13:06:42 +0000 Subject: [PATCH 156/203] Fix invulnerability damage and armour (#12190) --- .../features/0003-Entity-Activation-Range-2.0.patch | 8 ++++---- .../minecraft/world/entity/LivingEntity.java.patch | 13 ++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch index 40b1d941d..11abde7c3 100644 --- a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch @@ -366,7 +366,7 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f import org.slf4j.Logger; diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 8204528c26456929fdec0d8ba7a5a52128409097..01bc2d1639be9f04afc63e5841c5c99730ea37d8 100644 +index cdb4d313eb33c049c8467fe5d31fb0d671737768..40b799fd90b0db13bdaa8834c021f5ca8f25ce10 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -476,7 +476,7 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e681179343c7e75c3 100644 +index 54cf80831372d102e8d2966ac104678caebdf336..d89c3949e16ff6cb0374da29ec6731d854b5f105 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -381,6 +381,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -533,10 +533,10 @@ index b15420ffa1432d49aec8e91e917598bde4e94337..054ece1d539d69a4b7eec57e68117934 movement = this.maybeBackOffFromEdge(movement, type); Vec3 vec3 = this.collide(movement); diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index ff513e8c87bf42be756e46f4dbfec8dda2b8cb60..239c443ddc9bacc08a39a8ef2ab17016a2480549 100644 +index bf5fd2a6c8630ea2bb06881d4d365dda9a4e90ea..4713c29cc2add476f568163a29cb297f5d1049df 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3096,6 +3096,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3103,6 +3103,14 @@ public abstract class LivingEntity extends Entity implements Attackable { return false; } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index 862afaa4e..ed516d3b9 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -971,7 +971,7 @@ int i = (this.getEffect(MobEffects.DAMAGE_RESISTANCE).getAmplifier() + 1) * 5; int i1 = 25 - i; float f = damageAmount * i1; -@@ -1768,24 +_,212 @@ +@@ -1768,24 +_,219 @@ } } @@ -984,7 +984,11 @@ + if (invulnerabilityRelatedLastDamage == 0) return 0D; // no last damage, no reduction + // last damage existed, this means the reduction *technically* is (new damage - last damage). + // If the event damage was changed to something less than invul damage, hard lock it at 0. -+ if (d < invulnerabilityRelatedLastDamage) return 0D; ++ // ++ // Cast the passed in double down to a float as double -> float -> double is lossy. ++ // If last damage is a (float) 3.2D (since the events use doubles), we cannot compare ++ // the new damage value of this damage instance by upcasting it again to a double as 3.2D != (double) (float) 3.2D. ++ if (d.floatValue() < invulnerabilityRelatedLastDamage) return 0D; + return (double) -invulnerabilityRelatedLastDamage; + }; + final float originalInvulnerabilityReduction = invulnerabilityReductionEquation.apply((double) amount).floatValue(); @@ -1118,7 +1122,10 @@ + + // Apply damage to armor + if (!damageSource.is(DamageTypeTags.BYPASSES_ARMOR)) { -+ float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT)); ++ float armorDamage = (float) event.getDamage(); ++ armorDamage += (float) event.getDamage(DamageModifier.INVULNERABILITY_REDUCTION); ++ armorDamage += (float) event.getDamage(DamageModifier.BLOCKING); ++ armorDamage += (float) event.getDamage(DamageModifier.HARD_HAT); + this.hurtArmor(damageSource, armorDamage); + } + From b50662682477840fe4a12c9b2ff2c1e4e8d4070b Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Fri, 28 Feb 2025 17:58:45 +0100 Subject: [PATCH 157/203] Remove unused light queue size option (#12201) --- .../io/papermc/paper/configuration/RemovedConfigurations.java | 3 ++- .../io/papermc/paper/configuration/WorldConfiguration.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java b/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java index 8b9ff8042..7e4b27a6e 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/RemovedConfigurations.java @@ -54,7 +54,8 @@ interface RemovedConfigurations { path("fixes", "fix-curing-zombie-villager-discount-exploit"), path("entities", "mob-effects", "undead-immune-to-certain-effects"), path("entities", "entities-target-with-follow-range"), - path("environment", "disable-teleportation-suffocation-check") + path("environment", "disable-teleportation-suffocation-check"), + path("misc", "light-queue-size") }; // spawn.keep-spawn-loaded and spawn.keep-spawn-loaded-range are no longer used, but kept // in the world default config for compatibility with old worlds being migrated to use the gamerule diff --git a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java index d193330bf..84a5adb36 100644 --- a/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java +++ b/paper-server/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java @@ -558,7 +558,6 @@ public class WorldConfiguration extends ConfigurationPart { public Misc misc; public class Misc extends ConfigurationPart { - public int lightQueueSize = 20; public boolean updatePathfindingOnBlockUpdate = true; public boolean showSignClickCommandFailureMsgsToPlayer = false; public RedstoneImplementation redstoneImplementation = RedstoneImplementation.VANILLA; From 1d5e5a57e919d7d7b79cdd36e5194f63fc55cdce Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Fri, 28 Feb 2025 20:51:39 +0100 Subject: [PATCH 158/203] Document replacement for Skull owner profile methods (#12195) --- paper-api/src/main/java/org/bukkit/block/Skull.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/paper-api/src/main/java/org/bukkit/block/Skull.java b/paper-api/src/main/java/org/bukkit/block/Skull.java index 6cb7791e9..d6add557e 100644 --- a/paper-api/src/main/java/org/bukkit/block/Skull.java +++ b/paper-api/src/main/java/org/bukkit/block/Skull.java @@ -82,6 +82,8 @@ public interface Skull extends TileState { * may appear as the texture depending on skull type. * * @return the profile of the owning player + * + * @deprecated Use {@link #getPlayerProfile()} instead. */ @Nullable @Deprecated // Paper @@ -98,6 +100,8 @@ public interface Skull extends TileState { * @param profile the profile of the owning player * @throws IllegalArgumentException if the profile does not contain the * necessary information + * + * @deprecated Use {@link #setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile)} instead. */ @Deprecated // Paper void setOwnerProfile(@Nullable PlayerProfile profile); From 8de7e356fa0d92c5729da39264f766f23fc8e7c4 Mon Sep 17 00:00:00 2001 From: Dylan Date: Mon, 3 Mar 2025 08:46:20 -0800 Subject: [PATCH 159/203] Add null check to level ref in Entity constructor (#12218) --- .../sources/net/minecraft/world/entity/Entity.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2ca8aeca6..72b325c8e 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 @@ -192,7 +192,7 @@ this.entityData = builder.build(); this.setPos(0.0, 0.0, 0.0); this.eyeHeight = this.dimensions.eyeHeight(); -+ this.despawnTime = type == EntityType.PLAYER ? -1 : level.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit ++ this.despawnTime = level == null || type == EntityType.PLAYER ? -1 : level.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit } public boolean isColliding(BlockPos pos, BlockState state) { From a866e366b2d2c00d01935fd6b6b147fcd0e244be Mon Sep 17 00:00:00 2001 From: tgbhy Date: Wed, 5 Mar 2025 10:45:16 +0100 Subject: [PATCH 160/203] Fix MenuType.SMITHING JavaDocs (#12226) --- paper-api/src/main/java/org/bukkit/inventory/MenuType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/bukkit/inventory/MenuType.java b/paper-api/src/main/java/org/bukkit/inventory/MenuType.java index eb64a5ef2..6c26f3081 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/MenuType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/MenuType.java @@ -116,7 +116,7 @@ public interface MenuType extends Keyed, io.papermc.paper.world.flag.FeatureDepe */ MenuType.Typed> SHULKER_BOX = get("shulker_box"); /** - * A MenuType which represents a stonecutter. + * A MenuType which represents a smithing table. */ MenuType.Typed> SMITHING = get("smithing"); /** From 5538d24d72a418491b80e89d6f7710548ac46687 Mon Sep 17 00:00:00 2001 From: Vincenzo Reina Date: Wed, 5 Mar 2025 13:28:25 +0100 Subject: [PATCH 161/203] Fix "DEFAULT" SpawnReason of fish spawned by bucket (#12227) * Add SpawnReason "Bucket". Fix "DEFAULT" SpawnReason for entity spawning from mob bucket * Clarify SpawnReason description for bucket entity spawning --- .../org/bukkit/event/entity/CreatureSpawnEvent.java | 4 ++++ .../net/minecraft/world/item/MobBucketItem.java.patch | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/MobBucketItem.java.patch diff --git a/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java index 361db2562..0c3f8f3f6 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java @@ -211,6 +211,10 @@ public class CreatureSpawnEvent extends EntitySpawnEvent { * When an entity spawns from an ominous item spawner */ OMINOUS_ITEM_SPAWNER, + /** + * When an entity spawns from a bucket + */ + BUCKET, // Paper end - Fixes and additions to the SpawnReason API /** * When a creature is spawned by a potion effect, for example: diff --git a/paper-server/patches/sources/net/minecraft/world/item/MobBucketItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MobBucketItem.java.patch new file mode 100644 index 000000000..668262765 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/MobBucketItem.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/item/MobBucketItem.java ++++ b/net/minecraft/world/item/MobBucketItem.java +@@ -58,7 +_,7 @@ + } + + if (mob != null) { +- serverLevel.addFreshEntityWithPassengers(mob); ++ serverLevel.addFreshEntityWithPassengers(mob, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUCKET); // Paper - Add SpawnReason + mob.playAmbientSound(); + } + } From 0a4eb8f3bb452b673030afeaf44247f8ac472aa9 Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Fri, 7 Mar 2025 19:40:58 -0800 Subject: [PATCH 162/203] Send the pong response packet immediately. This packet is similar to the keep alive packet and is processed async. (#12242) --- ...imize-Network-Manager-and-add-advanced-packet-sup.patch | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch index ca477fbd3..6a1de7401 100644 --- a/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -28,7 +28,7 @@ and then catch exceptions and close if they fire. Part of this commit was authored by: Spottedleaf, sandtechnology diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c022d913d 100644 +index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42eafb96fa1 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -85,7 +85,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -232,7 +232,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c // Paper start - Add PlayerConnectionCloseEvent if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) { /* Player was logged in, either game listener or configuration listener */ -@@ -797,4 +888,96 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -797,4 +888,97 @@ public class Connection extends SimpleChannelInboundHandler> { public void setBandwidthLogger(LocalSampleLogger bandwithLogger) { this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwithLogger); } @@ -293,7 +293,8 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..161ee86d67b9a23368a18481fde9768c + packet instanceof net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket || + packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket || -+ packet instanceof net.minecraft.network.protocol.game.ClientboundBossEventPacket; ++ packet instanceof net.minecraft.network.protocol.game.ClientboundBossEventPacket || ++ packet instanceof net.minecraft.network.protocol.ping.ClientboundPongResponsePacket; + } + } + From 7a3d0c4e98c6e2b755aa31949fa5c8561db1ec5d Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Mar 2025 05:11:12 +0100 Subject: [PATCH 163/203] Fix recipe being always null in PrepareItemCraftEvent from the api (#12237) --- .../src/main/java/org/bukkit/craftbukkit/CraftServer.java | 1 + 1 file changed, 1 insertion(+) 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 a0a1ed48f..99beb7ec6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1725,6 +1725,7 @@ public final class CraftServer implements Server { if (recipe.isPresent()) { RecipeHolder recipeCrafting = recipe.get(); + inventoryCrafting.setCurrentRecipe(recipeCrafting); if (craftResult.setRecipeUsed(craftPlayer.getHandle(), recipeCrafting)) { itemstack = recipeCrafting.value().assemble(inventoryCrafting.asCraftInput(), craftWorld.getHandle().registryAccess()); } From a6ce734fd0f9c6e86ab3eab17e7490de95bd0e64 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Mar 2025 05:13:25 +0100 Subject: [PATCH 164/203] Fix zombie villager not dropping item once cured (#12230) --- .../sources/net/minecraft/world/entity/Mob.java.patch | 10 ++++++++++ .../world/entity/monster/ZombieVillager.java.patch | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch index 6e9bf95dd..deac63882 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch @@ -326,6 +326,16 @@ } } } +@@ -981,7 +_,9 @@ + double d = this.getEquipmentDropChance(equipmentSlot); + if (d > 1.0) { + this.setItemSlot(equipmentSlot, ItemStack.EMPTY); ++ this.forceDrops = true; // Paper - Add missing forceDrop toggles + this.spawnAtLocation(level, itemBySlot); ++ this.forceDrops = false; // Paper - Add missing forceDrop toggles + } + } + } @@ -1269,6 +_,22 @@ public T convertTo( EntityType entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion afterConversion diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch index d86b3f000..220356954 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch @@ -57,14 +57,6 @@ EntityType.VILLAGER, ConversionParams.single(this, false, false), villager -> { -@@ -223,6 +_,7 @@ - SlotAccess slot = villager.getSlot(equipmentSlot.getIndex() + 300); - slot.set(this.getItemBySlot(equipmentSlot)); - } -+ this.forceDrops = false; // CraftBukkit - - villager.setVillagerData(this.getVillagerData()); - if (this.gossips != null) { @@ -237,19 +_,24 @@ villager.finalizeSpawn(serverLevel, serverLevel.getCurrentDifficultyAt(villager.blockPosition()), EntitySpawnReason.CONVERSION, null); villager.refreshBrain(serverLevel); From ce3001621894ea775206abe455442d0aeeef3535 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Mar 2025 05:27:05 +0100 Subject: [PATCH 165/203] Skip alpha channel for custom model data component (#12205) --- .../item/PaperCustomModelData.java | 2 +- .../CraftCustomModelDataComponent.java | 20 ++++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperCustomModelData.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperCustomModelData.java index 33a93c8ac..e2f2d435b 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperCustomModelData.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperCustomModelData.java @@ -40,7 +40,7 @@ public record PaperCustomModelData( @Override public List colors() { - return MCUtil.transformUnmodifiable(this.impl.colors(), Color::fromRGB); + return MCUtil.transformUnmodifiable(this.impl.colors(), color -> Color.fromRGB(color & 0x00FFFFFF)); // skip alpha channel } static final class BuilderImpl implements CustomModelData.Builder { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftCustomModelDataComponent.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftCustomModelDataComponent.java index 09c6d22f8..d74f47c5c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftCustomModelDataComponent.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftCustomModelDataComponent.java @@ -1,6 +1,5 @@ package org.bukkit.craftbukkit.inventory.components; -import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; @@ -57,7 +56,7 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo @Override public void setFloats(List floats) { - this.handle = new CustomModelData(new ArrayList<>(floats), this.handle.flags(), this.handle.strings(), this.handle.colors()); + this.handle = new CustomModelData(List.copyOf(floats), this.handle.flags(), this.handle.strings(), this.handle.colors()); } @Override @@ -67,7 +66,7 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo @Override public void setFlags(List flags) { - this.handle = new CustomModelData(this.handle.floats(), List.copyOf(flags), this.handle.strings(), this.handle.colors()); // Paper + this.handle = new CustomModelData(this.handle.floats(), List.copyOf(flags), this.handle.strings(), this.handle.colors()); } @Override @@ -77,17 +76,17 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo @Override public void setStrings(List strings) { - this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), List.copyOf(strings), this.handle.colors()); // Paper + this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), List.copyOf(strings), this.handle.colors()); } @Override public List getColors() { - return this.getHandle().colors().stream().map(Color::fromRGB).toList(); + return this.getHandle().colors().stream().map(color -> Color.fromRGB(color & 0x00FFFFFF)).toList(); // skip alpha channel } @Override public void setColors(List colors) { - this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), this.handle.strings(), colors.stream().map(Color::asRGB).toList()); // Paper + this.handle = new CustomModelData(this.handle.floats(), this.handle.flags(), this.handle.strings(), colors.stream().map(Color::asRGB).toList()); } @Override @@ -95,14 +94,11 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo if (this == obj) { return true; } - if (obj == null) { - return false; - } - if (this.getClass() != obj.getClass()) { + if (obj == null || this.getClass() != obj.getClass()) { return false; } final CraftCustomModelDataComponent other = (CraftCustomModelDataComponent) obj; - return Objects.equals(this.handle, other.handle); + return this.handle.equals(other.handle); } @Override @@ -114,6 +110,6 @@ public final class CraftCustomModelDataComponent implements CustomModelDataCompo @Override public String toString() { - return "CraftCustomModelDataComponent{" + "handle=" + this.handle + '}'; + return "CraftCustomModelDataComponent{component=" + this.handle + '}'; } } From 4519857817618fc5e678b9e44e2bd3450f3afa53 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 8 Mar 2025 06:33:29 -0800 Subject: [PATCH 166/203] Set old position / rotation for newly created entities Set the old pos/rot to be the same as the current pos/rot for new entities as the default value for the old pos/rot is zero. Fixes https://github.com/PaperMC/Folia/issues/302 --- .../net/minecraft/server/level/ServerLevel.java.patch | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 245242b92..69e9d0f01 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -1072,6 +1072,14 @@ @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashReportCategory = super.fillReportDetails(report); +@@ -1714,6 +_,7 @@ + final class EntityCallbacks implements LevelCallback { + @Override + public void onCreated(Entity entity) { ++ entity.setOldPosAndRot(); // Paper - update old pos / rot for new entities as it will default to Vec3.ZERO + } + + @Override @@ -1723,24 +_,32 @@ @Override From 8e69d981fa14a34b327724817b7653bae9adfcb4 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Sat, 8 Mar 2025 11:38:50 -0800 Subject: [PATCH 167/203] Player - Expose player score (#12243) --- .../src/main/java/org/bukkit/entity/Player.java | 16 ++++++++++++++++ .../bukkit/craftbukkit/entity/CraftPlayer.java | 10 ++++++++++ 2 files changed, 26 insertions(+) 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 69f982d1d..494dca2ee 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Player.java +++ b/paper-api/src/main/java/org/bukkit/entity/Player.java @@ -3902,4 +3902,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM * @return the result of this method, holding leftovers and spawned items. */ PlayerGiveResult give(Collection items, boolean dropIfFull); + + /** + * Get the score that shows in the death screen of the player. + *

This amount is added to when the player gains experience.

+ * + * @return Death screen score of player + */ + int getDeathScreenScore(); + + /** + * Set the score that shows in the death screen of the player. + *

This amount is added to when the player gains experience.

+ * + * @param score New death screen score of player + */ + void setDeathScreenScore(int score); } 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 218a27def..a33c22827 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 @@ -3599,4 +3599,14 @@ public class CraftPlayer extends CraftHumanEntity implements Player { return forwardMovement == backwardMovement ? 0 : forwardMovement ? 1 : -1; } + + @Override + public int getDeathScreenScore() { + return getHandle().getScore(); + } + + @Override + public void setDeathScreenScore(final int score) { + getHandle().setScore(score); + } } From 2526fe063af4825e22df02196553b51db1b411c4 Mon Sep 17 00:00:00 2001 From: TonytheMacaroni Date: Sat, 8 Mar 2025 15:20:53 -0500 Subject: [PATCH 168/203] Add type to represent unimplemented data component types (#12222) --- .../paper/datacomponent/DataComponentAdapter.java | 8 ++++++++ .../datacomponent/DataComponentAdapters.java | 11 +++++++++-- .../datacomponent/PaperDataComponentType.java | 15 ++++++++++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapter.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapter.java index 957fdf1e3..611e4bf50 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapter.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapter.java @@ -15,10 +15,18 @@ public record DataComponentAdapter( ) { static final Function API_TO_UNIT_CONVERTER = $ -> Unit.INSTANCE; + static final Function API_TO_UNIMPLEMENTED_CONVERTER = $ -> { + throw new UnsupportedOperationException("Cannot convert an API value to an unimplemented type"); + }; + public boolean isValued() { return this.apiToVanilla != API_TO_UNIT_CONVERTER; } + public boolean isUnimplemented() { + return this.apiToVanilla == API_TO_UNIMPLEMENTED_CONVERTER; + } + public NMS toVanilla(final API value) { final NMS nms = this.apiToVanilla.apply(value); if (this.codecValidation) { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java index 767558820..b3c201527 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java @@ -63,6 +63,10 @@ public final class DataComponentAdapters { throw new UnsupportedOperationException("Cannot convert the Unit type to an API value"); }; + static final Function UNIMPLEMENTED_TO_API_CONVERTER = $ -> { + throw new UnsupportedOperationException("Cannot convert the an unimplemented type to an API value"); + }; + static final Map>, DataComponentAdapter> ADAPTERS = new HashMap<>(); public static void bootstrap() { @@ -136,10 +140,9 @@ public final class DataComponentAdapters { // register(DataComponents.LOCK, PaperLockCode::new); register(DataComponents.CONTAINER_LOOT, PaperSeededContainerLoot::new); - // TODO: REMOVE THIS... we want to build the PR... so lets just make things UNTYPED! for (final Map.Entry>, DataComponentType> componentType : BuiltInRegistries.DATA_COMPONENT_TYPE.entrySet()) { if (!ADAPTERS.containsKey(componentType.getKey())) { - registerUntyped((DataComponentType) componentType.getValue()); + registerUnimplemented(componentType.getValue()); } } } @@ -152,6 +155,10 @@ public final class DataComponentAdapters { registerInternal(type, Function.identity(), Function.identity(), true); } + public static void registerUnimplemented(final DataComponentType type) { + registerInternal(type, UNIMPLEMENTED_TO_API_CONVERTER, DataComponentAdapter.API_TO_UNIMPLEMENTED_CONVERTER, false); + } + private static > void register(final DataComponentType type, final Function vanillaToApi) { registerInternal(type, vanillaToApi, Handleable::getHandle, false); } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java index 7ec9b765f..e8fc0dda8 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/PaperDataComponentType.java @@ -77,7 +77,9 @@ public abstract class PaperDataComponentType implements DataComponentTyp if (adapter == null) { throw new IllegalArgumentException("No adapter found for " + key); } - if (adapter.isValued()) { + if (adapter.isUnimplemented()) { + return new Unimplemented<>(key, type, adapter); + } else if (adapter.isValued()) { return new ValuedImpl<>(key, type, adapter); } else { return new NonValuedImpl<>(key, type, adapter); @@ -105,4 +107,15 @@ public abstract class PaperDataComponentType implements DataComponentTyp super(key, type, adapter); } } + + public static final class Unimplemented extends PaperDataComponentType { + + public Unimplemented( + final NamespacedKey key, + final net.minecraft.core.component.DataComponentType type, + final DataComponentAdapter adapter + ) { + super(key, type, adapter); + } + } } From 20df25d3a53ff83addfc2d65faa65df5d2da5476 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Sat, 8 Mar 2025 21:31:21 +0100 Subject: [PATCH 169/203] Don't resync all attributes when updating scaled health (#12232) --- .../bukkit/craftbukkit/entity/CraftPlayer.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) 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 a33c22827..0e0abc233 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 @@ -2827,14 +2827,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } public void updateScaledHealth(boolean sendHealth) { - AttributeMap attributemapserver = this.getHandle().getAttributes(); - Collection set = attributemapserver.getSyncableAttributes(); - - this.injectScaledMaxHealth(set, true); - // SPIGOT-3813: Attributes before health if (this.getHandle().connection != null) { - this.getHandle().connection.send(new ClientboundUpdateAttributesPacket(this.getHandle().getId(), set)); + this.getHandle().connection.send(new ClientboundUpdateAttributesPacket(this.getHandle().getId(), Set.of(this.getScaledMaxHealth()))); if (sendHealth) { this.sendHealthUpdate(); } @@ -2874,8 +2869,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { break; } } + collection.add(getScaledMaxHealth()); + } + + public AttributeInstance getScaledMaxHealth() { AttributeInstance dummy = new AttributeInstance(Attributes.MAX_HEALTH, (attribute) -> { }); - // Spigot start double healthMod = this.scaledHealth ? this.healthScale : this.getMaxHealth(); if ( healthMod >= Float.MAX_VALUE || healthMod <= 0 ) { @@ -2883,8 +2881,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getServer().getLogger().warning( this.getName() + " tried to crash the server with a large health attribute" ); } dummy.setBaseValue(healthMod); - // Spigot end - collection.add(dummy); + return dummy; } @Override From 43f37b1b5ea4dab263a6b4d7e0881f8c610fdbb4 Mon Sep 17 00:00:00 2001 From: Esophose Date: Sat, 8 Mar 2025 13:38:14 -0700 Subject: [PATCH 170/203] Remove ItemFactory#enchantWithLevels range check for vanilla parity (#12209) --- .../src/main/java/org/bukkit/inventory/ItemFactory.java | 8 ++++---- .../src/main/java/org/bukkit/inventory/ItemStack.java | 8 ++++---- .../bukkit/craftbukkit/inventory/CraftItemFactory.java | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) 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 0a814c1f6..c1ee9659f 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemFactory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -327,7 +327,7 @@ public interface ItemFactory { * *

If the provided ItemStack is already enchanted, the existing enchants will be removed before enchanting.

* - *

Levels must be in range {@code [1, 30]}.

+ *

Enchantment tables use levels in the range {@code [1, 30]}.

* * @param itemStack ItemStack to enchant * @param levels levels to use for enchanting @@ -336,7 +336,7 @@ public interface ItemFactory { * @return enchanted copy of the provided ItemStack * @throws IllegalArgumentException on bad arguments */ - @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, boolean allowTreasure, @NotNull java.util.Random random); + @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, int levels, boolean allowTreasure, @NotNull java.util.Random random); // Paper end - enchantWithLevels API // Paper start - enchantWithLevels with tag specification /** @@ -344,7 +344,7 @@ public interface ItemFactory { * *

If the provided ItemStack is already enchanted, the existing enchants will be removed before enchanting.

* - *

Levels must be in range {@code [1, 30]}.

+ *

Enchantment tables use levels in the range {@code [1, 30]}.

* * @param itemStack ItemStack to enchant * @param levels levels to use for enchanting @@ -353,6 +353,6 @@ public interface ItemFactory { * @return enchanted copy of the provided ItemStack * @throws IllegalArgumentException on bad arguments */ - @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, @NotNull java.util.Random random); + @NotNull ItemStack enchantWithLevels(@NotNull ItemStack itemStack, int levels, @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, @NotNull java.util.Random random); // Paper end - enchantWithLevels with tag specification } 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 c84cddac8..5644b3501 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -683,7 +683,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat * *

If this ItemStack is already enchanted, the existing enchants will be removed before enchanting.

* - *

Levels must be in range {@code [1, 30]}.

+ *

Enchantment tables use levels in the range {@code [1, 30]}.

* * @param levels levels to use for enchanting * @param allowTreasure whether to allow enchantments where {@link org.bukkit.enchantments.Enchantment#isTreasure()} returns true @@ -692,7 +692,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat * @throws IllegalArgumentException on bad arguments */ @NotNull - public ItemStack enchantWithLevels(final @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, final boolean allowTreasure, final @NotNull java.util.Random random) { + public ItemStack enchantWithLevels(final int levels, final boolean allowTreasure, final @NotNull java.util.Random random) { return Bukkit.getServer().getItemFactory().enchantWithLevels(this, levels, allowTreasure, random); } @@ -701,7 +701,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat * *

If the provided ItemStack is already enchanted, the existing enchants will be removed before enchanting.

* - *

Levels must be in range {@code [1, 30]}.

+ *

Enchantment tables use levels in the range {@code [1, 30]}.

* * @param levels levels to use for enchanting * @param keySet registry key set defining the set of possible enchantments, e.g. {@link io.papermc.paper.registry.keys.tags.EnchantmentTagKeys#IN_ENCHANTING_TABLE}. @@ -709,7 +709,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat * @return enchanted copy of the provided ItemStack * @throws IllegalArgumentException on bad arguments */ - public @NotNull ItemStack enchantWithLevels(final @org.jetbrains.annotations.Range(from = 1, to = 30) int levels, final @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, final @NotNull java.util.Random random) { + public @NotNull ItemStack enchantWithLevels(final int levels, final @NotNull io.papermc.paper.registry.set.RegistryKeySet<@NotNull Enchantment> keySet, final @NotNull java.util.Random random) { return Bukkit.getItemFactory().enchantWithLevels(this, levels, keySet, random); } 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 424a1495b..10edd98d1 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 @@ -349,7 +349,6 @@ public final class CraftItemFactory implements ItemFactory { ) { Preconditions.checkArgument(itemStack != null, "Argument 'itemStack' must not be null"); Preconditions.checkArgument(!itemStack.isEmpty(), "Argument 'itemStack' cannot be empty"); - Preconditions.checkArgument(levels > 0 && levels <= 30, "Argument 'levels' must be in range [1, 30] (attempted " + levels + ")"); Preconditions.checkArgument(random != null, "Argument 'random' must not be null"); final net.minecraft.world.item.ItemStack internalStack = CraftItemStack.asNMSCopy(itemStack); if (internalStack.isEnchanted()) { From a2b0ff0644e76fb4a644d870bc335bf81bc6a109 Mon Sep 17 00:00:00 2001 From: Noah van der Aa Date: Sat, 8 Mar 2025 22:52:10 +0100 Subject: [PATCH 171/203] Fix cancelling PlayerInteractEvent at (0, 0, 0) (#12215) --------- Co-authored-by: Warrior <50800980+warriorrrr@users.noreply.github.com> --- .../server/level/ServerPlayerGameMode.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index df1886611..23cb42271 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -167,6 +167,15 @@ if (!blockState.isAir() && f >= 1.0F) { this.destroyAndAck(pos, sequence, "insta mine"); } else { +@@ -188,7 +_,7 @@ + this.lastSentState = i; + } + } else if (action == ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK) { +- if (pos.equals(this.destroyPos)) { ++ if (this.isDestroyingBlock && pos.equals(this.destroyPos)) { // Paper - require isDestroyingBlock to be true (special condition for when destroy pos is 0,0,0 and the event is cancelled) + int i1 = this.gameTicks - this.destroyProgressStart; + BlockState blockStatex = this.level.getBlockState(pos); + if (!blockStatex.isAir()) { @@ -212,14 +_,22 @@ this.debugLogging(pos, true, sequence, "stopped destroying"); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { From df96f8a0fa55a51917da7055da483d869036c0db Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Mar 2025 22:59:43 +0100 Subject: [PATCH 172/203] Correctly handle events for end portal (#12246) --- .../minecraft/world/level/block/EndPortalBlock.java.patch | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch index 436949f5f..a63044ae4 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch @@ -34,7 +34,7 @@ f = Direction.WEST.toYRot(); set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)); if (entity instanceof ServerPlayer) { -@@ -88,15 +_,21 @@ +@@ -88,15 +_,23 @@ f = 0.0F; set = Relative.union(Relative.DELTA, Relative.ROTATION); if (entity instanceof ServerPlayer serverPlayer) { @@ -49,13 +49,15 @@ - level1, bottomCenter, Vec3.ZERO, f, 0.0F, set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET) - ); + // CraftBukkit start -+ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(bottomCenter, level1.getWorld(), f, entity.getXRot()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); ++ set.removeAll(Relative.ROTATION); // remove relative rotation flags to simplify event mutation ++ float absoluteYaw = flag ? f : entity.getYRot() + f; ++ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(bottomCenter, level1.getWorld(), absoluteYaw, entity.getXRot()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); + if (event == null) { + return null; + } + org.bukkit.Location to = event.getTo(); + -+ return new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3D(to), entity.getDeltaMovement(), to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL); ++ return new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3D(to), Vec3.ZERO, to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL); + // CraftBukkit end } } From 2565497897b91af2e7bbe98e4fd7d5fce5116ff7 Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:02:10 +0100 Subject: [PATCH 173/203] Cancel PlayerLaunchProjectileEvent properly for enderpearls (#12223) --- .../net/minecraft/world/item/EnderpearlItem.java.patch | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch index 0b1cbebad..5b8ef433b 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/EnderpearlItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/EnderpearlItem.java +++ b/net/minecraft/world/item/EnderpearlItem.java -@@ -21,22 +_,38 @@ +@@ -21,22 +_,42 @@ @Override public InteractionResult use(Level level, Player player, InteractionHand hand) { ItemStack itemInHand = player.getItemInHand(hand); @@ -39,7 +39,11 @@ + ); + player.awardStat(Stats.ITEM_USED.get(this)); + } else { -+ // Paper end - PlayerLaunchProjectileEvent ++ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) { ++ serverPlayer.deregisterEnderPearl(thrownEnderpearl.projectile()); ++ serverPlayer.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(player.getCooldowns().getCooldownGroup(itemInHand), 0)); // prevent visual desync of cooldown on the slot ++ } ++ // Paper end - PlayerLaunchProjectileEvent + player.containerMenu.sendAllDataToRemote(); + return InteractionResult.FAIL; + } From 34c794dc51305e50c315e07e555a4ba10c208357 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Sat, 8 Mar 2025 14:09:40 -0800 Subject: [PATCH 174/203] ServerTickManager#requestGameToSprint - Silence command like feedback (#12220) * CraftServerTickManager - silence feedback when sprinting * CraftServerTickManager - forgot secondary note * ServerTickRateManager - only set to silent if not already sprinting --- .../server/ServerTickRateManager.java.patch | 36 +++++++++++++++++++ .../craftbukkit/CraftServerTickManager.java | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 paper-server/patches/sources/net/minecraft/server/ServerTickRateManager.java.patch diff --git a/paper-server/patches/sources/net/minecraft/server/ServerTickRateManager.java.patch b/paper-server/patches/sources/net/minecraft/server/ServerTickRateManager.java.patch new file mode 100644 index 000000000..9258d5414 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/ServerTickRateManager.java.patch @@ -0,0 +1,36 @@ +--- a/net/minecraft/server/ServerTickRateManager.java ++++ b/net/minecraft/server/ServerTickRateManager.java +@@ -14,6 +_,7 @@ + private long scheduledCurrentSprintTicks = 0L; + private boolean previousIsFrozen = false; + private final MinecraftServer server; ++ private boolean silent; // Paper - silence feedback when API requests sprint + + public ServerTickRateManager(MinecraftServer server) { + this.server = server; +@@ -67,6 +_,13 @@ + } + + public boolean requestGameToSprint(int sprintTime) { ++ // Paper start - silence feedback when API requests sprint ++ return requestGameToSprint(sprintTime, false); ++ } ++ ++ public boolean requestGameToSprint(int sprintTime, boolean silent) { ++ if (!isSprinting()) this.silent = silent; ++ // Paper end - silence feedback when API requests sprint + boolean flag = this.remainingSprintTicks > 0L; + this.sprintTimeSpend = 0L; + this.scheduledCurrentSprintTicks = sprintTime; +@@ -83,7 +_,10 @@ + String string = String.format("%.2f", l == 0L ? this.millisecondsPerTick() : d / l); + this.scheduledCurrentSprintTicks = 0L; + this.sprintTimeSpend = 0L; +- this.server.createCommandSourceStack().sendSuccess(() -> Component.translatable("commands.tick.sprint.report", i, string), true); ++ // Paper start - silence feedback when API requests sprint ++ if (!this.silent) this.server.createCommandSourceStack().sendSuccess(() -> Component.translatable("commands.tick.sprint.report", i, string), true); ++ this.silent = false; ++ // Paper end - silence feedback when API requests sprint + this.remainingSprintTicks = 0L; + this.setFrozen(this.previousIsFrozen); + this.server.onTickRateChanged(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServerTickManager.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServerTickManager.java index cdc55d070..f14759011 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServerTickManager.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServerTickManager.java @@ -72,7 +72,7 @@ final class CraftServerTickManager implements ServerTickManager { @Override public boolean requestGameToSprint(final int ticks) { - return this.manager.requestGameToSprint(ticks); + return this.manager.requestGameToSprint(ticks, true); } @Override From 3d13b115147a459cb11a8e6a1a493c19a4aa9198 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sun, 9 Mar 2025 10:28:05 +0100 Subject: [PATCH 175/203] fix: switch back to using a snapshot for velocity-natives we delete old snapshots (age > 10 days), keeping only the last 5 at minimum --- paper-server/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index 84d1b6783..b3a223e15 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -137,7 +137,7 @@ dependencies { runtimeOnly(log4jPlugins.output) alsoShade(log4jPlugins.output) - implementation("com.velocitypowered:velocity-native:3.4.0-20250222.161222-36") { + implementation("com.velocitypowered:velocity-native:3.4.0-SNAPSHOT") { isTransitive = false } implementation("io.netty:netty-codec-haproxy:4.1.115.Final") // Add support for proxy protocol From 7afae7f46547c9f37679f8f641ee490de2a5e293 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:14:44 +0100 Subject: [PATCH 176/203] Add client tick end event (#12199) --- .../event/packet/ClientTickEndEvent.java | 29 +++++++++++++++++++ .../ServerGamePacketListenerImpl.java.patch | 11 +++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/event/packet/ClientTickEndEvent.java diff --git a/paper-api/src/main/java/io/papermc/paper/event/packet/ClientTickEndEvent.java b/paper-api/src/main/java/io/papermc/paper/event/packet/ClientTickEndEvent.java new file mode 100644 index 000000000..78227fd5f --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/packet/ClientTickEndEvent.java @@ -0,0 +1,29 @@ +package io.papermc.paper.event.packet; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a {@code minecraft:client_tick_end} packet is received by the server. + */ +@NullMarked +public class ClientTickEndEvent extends PlayerEvent { + private static final HandlerList HANDLER_LIST = new HandlerList(); + + @ApiStatus.Internal + public ClientTickEndEvent(final Player player) { + super(player); + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} 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 8589a3b4e..ba6e737d4 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 @@ -70,7 +70,7 @@ private double firstGoodX; private double firstGoodY; private double firstGoodZ; -@@ -236,22 +_,39 @@ +@@ -236,22 +_,41 @@ private int receivedMovePacketCount; private int knownMovePacketCount; private boolean receivedMovementThisTick; @@ -98,6 +98,7 @@ private final FutureChain chatMessageChain; private boolean waitingForSwitchToConfig; + private static final int MAX_SIGN_LINE_LENGTH = Integer.getInteger("Paper.maxSignLength", 80); // Paper - Limit client sign length ++ private final io.papermc.paper.event.packet.ClientTickEndEvent tickEndEvent; // Paper - add client tick end event public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player, CommonListenerCookie cookie) { - super(server, connection, cookie); @@ -109,6 +110,7 @@ this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(player.getUUID(), server::enforceSecureProfile); - this.chatMessageChain = new FutureChain(server); + this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat ++ this.tickEndEvent = new io.papermc.paper.event.packet.ClientTickEndEvent(player.getBukkitEntity()); // Paper - add client tick end event } @Override @@ -2598,7 +2600,7 @@ this.signedMessageDecoder = chatSession.createMessageDecoder(this.player.getUUID()); this.chatMessageChain .append( -@@ -1919,15 +_,17 @@ +@@ -1919,19 +_,22 @@ this.server .getPlayerList() .broadcastAll( @@ -2620,6 +2622,11 @@ @Override public void handleClientTickEnd(ServerboundClientTickEndPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); ++ this.tickEndEvent.callEvent(); // Paper - add client tick end event + if (!this.receivedMovementThisTick) { + this.player.setKnownMovement(Vec3.ZERO); + } @@ -1957,4 +_,17 @@ interface EntityInteraction { InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); From e5d988df858e24fc94a5a5ccd91e382e7f404724 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 9 Mar 2025 18:38:42 +0100 Subject: [PATCH 177/203] Revert "Fix cancelling PlayerInteractEvent at (0, 0, 0) (#12215)" This reverts commit a2b0ff0644e76fb4a644d870bc335bf81bc6a109. --- ...on-checking-in-player-move-packet-ha.patch | 20 +++++++++---------- ...vement-for-vehicles-players-unaffect.patch | 6 +++--- .../level/ServerPlayerGameMode.java.patch | 9 --------- 3 files changed, 13 insertions(+), 22 deletions(-) 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 00cdbd326..b4c29ffe9 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,10 +6,10 @@ 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 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d149849983107c539b31 100644 +index addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d7901f814ce 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -561,7 +561,7 @@ public class ServerGamePacketListenerImpl +@@ -563,7 +563,7 @@ public class ServerGamePacketListenerImpl return; } @@ -18,7 +18,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above -@@ -571,6 +571,7 @@ public class ServerGamePacketListenerImpl +@@ -573,6 +573,7 @@ public class ServerGamePacketListenerImpl } rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5)); @@ -26,7 +26,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 double verticalDelta = d4; // Paper - Decompile fix, was named d11 previously, is now gone in the source d3 = d - rootVehicle.getX(); d4 = d1 - rootVehicle.getY(); -@@ -582,14 +583,22 @@ public class ServerGamePacketListenerImpl +@@ -584,14 +585,22 @@ public class ServerGamePacketListenerImpl d7 = d3 * d3 + d4 * d4 + d5 * d5; boolean flag2 = false; if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot @@ -52,7 +52,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 rootVehicle.absMoveTo(x, y, z, f, f1); this.player.absMoveTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle)); -@@ -667,9 +676,32 @@ public class ServerGamePacketListenerImpl +@@ -669,9 +678,32 @@ public class ServerGamePacketListenerImpl } private boolean noBlocksAround(Entity entity) { @@ -88,7 +88,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 } @Override -@@ -1368,7 +1400,7 @@ public class ServerGamePacketListenerImpl +@@ -1370,7 +1402,7 @@ public class ServerGamePacketListenerImpl } } @@ -97,7 +97,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 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 -@@ -1407,6 +1439,7 @@ public class ServerGamePacketListenerImpl +@@ -1409,6 +1441,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 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1439,7 +1472,17 @@ public class ServerGamePacketListenerImpl +@@ -1441,7 +1474,17 @@ public class ServerGamePacketListenerImpl } // Paper start - Add fail move event @@ -124,7 +124,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 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); -@@ -1575,7 +1618,7 @@ public class ServerGamePacketListenerImpl +@@ -1577,7 +1620,7 @@ public class ServerGamePacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -133,7 +133,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310 this.awaitingTeleportTime = this.tickCount; this.teleport( this.awaitingPositionFromClient.x, -@@ -1594,6 +1637,33 @@ public class ServerGamePacketListenerImpl +@@ -1596,6 +1639,33 @@ public class ServerGamePacketListenerImpl } } diff --git a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch index ad20395cf..e0245475d 100644 --- a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch +++ b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch @@ -11,10 +11,10 @@ a portal in spectator mode and then later switching to creative mode would portal the player. diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba16a57313b 100644 +index 27718a20666a3edc0b036e4cdeda5d7901f814ce..727792ca1a2c9044abb1d404fbf8420652e1507c 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -657,7 +657,7 @@ public class ServerGamePacketListenerImpl +@@ -659,7 +659,7 @@ public class ServerGamePacketListenerImpl // CraftBukkit end this.player.serverLevel().getChunkSource().move(this.player); @@ -23,7 +23,7 @@ index 366c26b2ca539be189b67d75ae73a587c4102c14..4068132a33f87dd07d6df1033ed11ba1 Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z); this.handlePlayerKnownMovement(vec3); rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3); -@@ -1574,7 +1574,7 @@ public class ServerGamePacketListenerImpl +@@ -1576,7 +1576,7 @@ public class ServerGamePacketListenerImpl Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z); this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3); this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround()); diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 23cb42271..df1886611 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -167,15 +167,6 @@ if (!blockState.isAir() && f >= 1.0F) { this.destroyAndAck(pos, sequence, "insta mine"); } else { -@@ -188,7 +_,7 @@ - this.lastSentState = i; - } - } else if (action == ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK) { -- if (pos.equals(this.destroyPos)) { -+ if (this.isDestroyingBlock && pos.equals(this.destroyPos)) { // Paper - require isDestroyingBlock to be true (special condition for when destroy pos is 0,0,0 and the event is cancelled) - int i1 = this.gameTicks - this.destroyProgressStart; - BlockState blockStatex = this.level.getBlockState(pos); - if (!blockStatex.isAir()) { @@ -212,14 +_,22 @@ this.debugLogging(pos, true, sequence, "stopped destroying"); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { From 743346a5da36015063d834ecd6013fa40913e5f8 Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Fri, 7 Mar 2025 17:57:18 -0800 Subject: [PATCH 178/203] Force update attributes See https://github.com/PaperMC/Paper/pull/12241/ --- ...on-checking-in-player-move-packet-ha.patch | 12 ++-- ...vement-for-vehicles-players-unaffect.patch | 4 +- .../ServerGamePacketListenerImpl.java.patch | 60 ++++++++++++++++--- 3 files changed, 61 insertions(+), 15 deletions(-) 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 b4c29ffe9..5f5108129 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 addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d7901f814ce 100644 +index 12c83cb084563a4e3f7f357d8b600941544ef2b0..90e582ca30851857add5e2d830e9876667fd1807 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -563,7 +563,7 @@ public class ServerGamePacketListenerImpl @@ -88,7 +88,7 @@ index addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d79 } @Override -@@ -1370,7 +1402,7 @@ public class ServerGamePacketListenerImpl +@@ -1371,7 +1403,7 @@ public class ServerGamePacketListenerImpl } } @@ -97,7 +97,7 @@ index addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d79 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 -@@ -1409,6 +1441,7 @@ public class ServerGamePacketListenerImpl +@@ -1410,6 +1442,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 addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d79 // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1441,7 +1474,17 @@ public class ServerGamePacketListenerImpl +@@ -1442,7 +1475,17 @@ public class ServerGamePacketListenerImpl } // Paper start - Add fail move event @@ -124,7 +124,7 @@ index addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d79 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); -@@ -1577,7 +1620,7 @@ public class ServerGamePacketListenerImpl +@@ -1578,7 +1621,7 @@ public class ServerGamePacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -133,7 +133,7 @@ index addeb449904ec9a2ef59b99022787bee689b83cf..27718a20666a3edc0b036e4cdeda5d79 this.awaitingTeleportTime = this.tickCount; this.teleport( this.awaitingPositionFromClient.x, -@@ -1596,6 +1639,33 @@ public class ServerGamePacketListenerImpl +@@ -1597,6 +1640,33 @@ public class ServerGamePacketListenerImpl } } diff --git a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch index e0245475d..72a1e59c2 100644 --- a/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch +++ b/paper-server/patches/features/0031-Do-not-record-movement-for-vehicles-players-unaffect.patch @@ -11,7 +11,7 @@ a portal in spectator mode and then later switching to creative mode would portal the player. diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 27718a20666a3edc0b036e4cdeda5d7901f814ce..727792ca1a2c9044abb1d404fbf8420652e1507c 100644 +index 90e582ca30851857add5e2d830e9876667fd1807..c569cdfa4cba4f65892ffd4045c611837049f440 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -659,7 +659,7 @@ public class ServerGamePacketListenerImpl @@ -23,7 +23,7 @@ index 27718a20666a3edc0b036e4cdeda5d7901f814ce..727792ca1a2c9044abb1d404fbf84206 Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z); this.handlePlayerKnownMovement(vec3); rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3); -@@ -1576,7 +1576,7 @@ public class ServerGamePacketListenerImpl +@@ -1577,7 +1577,7 @@ public class ServerGamePacketListenerImpl Vec3 vec3 = new Vec3(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z); this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3); this.player.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.isOnGround()); 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 ba6e737d4..a46256fdd 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 @@ -547,7 +547,7 @@ addBlockDataToItem(blockState, serverLevel, blockPos, cloneItemStack); } -@@ -685,14 +_,24 @@ +@@ -685,18 +_,29 @@ if (stack.isItemEnabled(this.player.level().enabledFeatures())) { Inventory inventory = this.player.getInventory(); int i = inventory.findSlotMatchingItem(stack); @@ -576,6 +576,11 @@ } this.player.connection.send(new ClientboundSetHeldSlotPacket(inventory.selected)); + this.player.inventoryMenu.broadcastChanges(); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. + } + } + @@ -814,6 +_,13 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); int item = packet.getItem(); @@ -1072,7 +1077,7 @@ if (this.player.hasClientLoaded()) { BlockPos pos = packet.getPos(); this.player.resetLastActionTime(); -@@ -1101,14 +_,46 @@ +@@ -1101,32 +_,95 @@ case SWAP_ITEM_WITH_OFFHAND: if (!this.player.isSpectator()) { ItemStack itemInHand = this.player.getItemInHand(InteractionHand.OFF_HAND); @@ -1098,6 +1103,7 @@ + } + // CraftBukkit end this.player.stopUsingItem(); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } return; @@ -1119,14 +1125,21 @@ + } + // CraftBukkit end this.player.drop(false); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } -@@ -1120,13 +_,39 @@ + return; + case DROP_ALL_ITEMS: + if (!this.player.isSpectator()) { + this.player.drop(true); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. + } return; case RELEASE_USE_ITEM: - this.player.releaseUsingItem(); + if (this.player.getUseItem() == this.player.getItemInHand(this.player.getUsedItemHand())) this.player.releaseUsingItem(); // Paper - validate use item before processing release ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. return; case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: @@ -1159,6 +1172,7 @@ + } + } + // Paper end - Send block entities after destroy prediction ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. return; default: throw new IllegalArgumentException("Invalid player action"); @@ -1229,6 +1243,14 @@ } else { Component component1 = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED); this.player.sendSystemMessage(component1, true); +@@ -1187,6 +_,7 @@ + + this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos)); + this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction))); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. + } else { + LOGGER.warn( + "Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.", @@ -1203,6 +_,8 @@ @Override public void handleUseItem(ServerboundUseItemPacket packet) { @@ -1354,7 +1376,7 @@ throw new IllegalArgumentException("Expected packet sequence nr >= 0"); } else { this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo); -@@ -1275,7 +_,17 @@ +@@ -1275,20 +_,38 @@ @Override public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); @@ -1372,8 +1394,10 @@ if (this.player.getInventory().selected != packet.getSlot() && this.player.getUsedItemHand() == InteractionHand.MAIN_HAND) { this.player.stopUsingItem(); } -@@ -1284,11 +_,18 @@ + + this.player.getInventory().selected = packet.getSlot(); this.player.resetLastActionTime(); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } else { LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); + this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // CraftBukkit // Paper - kick event cause @@ -1956,7 +1980,7 @@ ServerGamePacketListenerImpl.LOGGER .warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString()); } -@@ -1656,6 +_,26 @@ +@@ -1656,6 +_,27 @@ ); } } @@ -1980,6 +2004,7 @@ + }); + } + // Paper end - PlayerUseUnknownEntityEvent ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } } @@ -2381,6 +2406,14 @@ for (Entry entry : Int2ObjectMaps.fastIterable(packet.getChangedSlots())) { this.player.containerMenu.setRemoteSlotNoCopy(entry.getIntKey(), entry.getValue()); +@@ -1726,6 +_,7 @@ + } else { + this.player.containerMenu.broadcastChanges(); + } ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. + } + } + } @@ -1733,6 +_,14 @@ @Override @@ -2450,7 +2483,15 @@ this.player.resetLastActionTime(); if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) { if (!this.player.containerMenu.stillValid(this.player)) { -@@ -1792,6 +_,43 @@ +@@ -1776,6 +_,7 @@ + if (flag) { + this.player.containerMenu.broadcastChanges(); + } ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. + } + } + } +@@ -1792,10 +_,48 @@ boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize(); @@ -2494,6 +2535,11 @@ if (flag1 && flag2) { this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack); this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack); + this.player.inventoryMenu.broadcastChanges(); ++ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. + } else if (flag && flag2) { + if (this.dropSpamThrottler.isUnderThreshold()) { + this.dropSpamThrottler.increment(); @@ -1809,11 +_,24 @@ @Override From 1a7288aa05cfb0a168850a7cc879f55235fe5934 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 9 Mar 2025 10:54:40 -0700 Subject: [PATCH 179/203] Adjust unloaded chunk check for block digging --- .../server/network/ServerGamePacketListenerImpl.java.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a46256fdd..213726106 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 @@ -1145,7 +1145,7 @@ case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: + // Paper start - Don't allow digging into unloaded chunks -+ if (this.player.level().getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4) == null) { ++ if (this.player.level().getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4) == null || !this.player.canInteractWithBlock(pos, 1.0)) { + this.player.connection.ackBlockChangesUpTo(packet.getSequence()); + return; + } From f4f275519f7c1fbe9db173b7144a4fe81440e365 Mon Sep 17 00:00:00 2001 From: Github-Citizen <80302627+Github-Citizen@users.noreply.github.com> Date: Sun, 9 Mar 2025 16:58:56 -0400 Subject: [PATCH 180/203] [ci skip] Clarify BlockFadeEvent#getNewState javadocs (#12250) --- .../main/java/org/bukkit/event/block/BlockFadeEvent.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockFadeEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockFadeEvent.java index 362643de4..f5a5ebb48 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockFadeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockFadeEvent.java @@ -33,11 +33,11 @@ public class BlockFadeEvent extends BlockEvent implements Cancellable { } /** - * Gets the state of the block that will be fading, melting or - * disappearing. + * Gets the state of the new block that will replace the block + * fading, melting or disappearing. * - * @return The block state of the block that will be fading, melting or - * disappearing + * @return The block state of the new block that replaces the block + * fading, melting or disappearing */ @NotNull public BlockState getNewState() { From 102c8bbc5414b157381bd0b1298144d6a3d97285 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:09:27 +0100 Subject: [PATCH 181/203] Add config for updating equipment on player actions (#12275) --- .../ServerGamePacketListenerImpl.java.patch | 24 +++++++++---------- .../configuration/GlobalConfiguration.java | 2 ++ 2 files changed, 14 insertions(+), 12 deletions(-) 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 213726106..c938c7bb9 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 @@ -577,7 +577,7 @@ this.player.connection.send(new ClientboundSetHeldSlotPacket(inventory.selected)); this.player.inventoryMenu.broadcastChanges(); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } } @@ -1103,7 +1103,7 @@ + } + // CraftBukkit end this.player.stopUsingItem(); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } return; @@ -1125,21 +1125,21 @@ + } + // CraftBukkit end this.player.drop(false); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } return; case DROP_ALL_ITEMS: if (!this.player.isSpectator()) { this.player.drop(true); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } return; case RELEASE_USE_ITEM: - this.player.releaseUsingItem(); + if (this.player.getUseItem() == this.player.getItemInHand(this.player.getUsedItemHand())) this.player.releaseUsingItem(); // Paper - validate use item before processing release -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. return; case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: @@ -1172,7 +1172,7 @@ + } + } + // Paper end - Send block entities after destroy prediction -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. return; default: throw new IllegalArgumentException("Invalid player action"); @@ -1247,7 +1247,7 @@ this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos)); this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction))); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } else { LOGGER.warn( "Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.", @@ -1397,7 +1397,7 @@ this.player.getInventory().selected = packet.getSlot(); this.player.resetLastActionTime(); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } else { LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); + this.disconnect(Component.literal("Invalid hotbar selection (Hacking?)"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // CraftBukkit // Paper - kick event cause @@ -2004,7 +2004,7 @@ + }); + } + // Paper end - PlayerUseUnknownEntityEvent -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } } @@ -2410,7 +2410,7 @@ } else { this.player.containerMenu.broadcastChanges(); } -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } } } @@ -2487,7 +2487,7 @@ if (flag) { this.player.containerMenu.broadcastChanges(); } -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } } } @@ -2536,7 +2536,7 @@ this.player.inventoryMenu.getSlot(packet.slotNum()).setByPlayer(itemStack); this.player.inventoryMenu.setRemoteSlot(packet.slotNum(), itemStack); this.player.inventoryMenu.broadcastChanges(); -+ this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdatesPublic(); // Paper - Force update attributes. } else if (flag && flag2) { if (this.dropSpamThrottler.isUnderThreshold()) { this.dropSpamThrottler.increment(); 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 42777adb0..a35391646 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 @@ -184,6 +184,8 @@ public class GlobalConfiguration extends ConfigurationPart { public boolean skipVanillaDamageTickWhenShieldBlocked = false; @Comment("This setting controls what compression format is used for region files.") public CompressionFormat compressionFormat = CompressionFormat.ZLIB; + @Comment("This setting controls if equipment should be updated when handling certain player actions.") + public boolean updateEquipmentOnPlayerActions = true; public enum CompressionFormat { GZIP, From f0388e2f3840c6f9577b389ccd163e172ce563bd Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Wed, 12 Mar 2025 07:13:47 -0300 Subject: [PATCH 182/203] Call EntityPushedByEntityAttackEvent for Mace AoE (#12257) --- .../sources/net/minecraft/world/item/MaceItem.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch index cfeffcdd8..908812946 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/MaceItem.java.patch @@ -15,3 +15,12 @@ ServerLevel serverLevel = (ServerLevel)attacker.level(); attacker.setDeltaMovement(attacker.getDeltaMovement().with(Direction.Axis.Y, 0.01F)); if (attacker instanceof ServerPlayer serverPlayer) { +@@ -139,7 +_,7 @@ + double knockbackPower = getKnockbackPower(attacker, livingEntity, vec3); + Vec3 vec31 = vec3.normalize().scale(knockbackPower); + if (knockbackPower > 0.0) { +- livingEntity.push(vec31.x, 0.7F, vec31.z); ++ livingEntity.push(vec31.x, 0.7F, vec31.z, attacker); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent + if (livingEntity instanceof ServerPlayer serverPlayer) { + serverPlayer.connection.send(new ClientboundSetEntityMotionPacket(serverPlayer)); + } From c37b890c8bb59cdc19043dce915fe3fe2c1db22f Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Thu, 13 Mar 2025 12:27:12 +0100 Subject: [PATCH 183/203] More deferred requireNonNull message creation --- .../src/main/java/org/bukkit/NamespacedKey.java | 17 ++++++++--------- .../src/main/java/org/bukkit/Registry.java | 2 +- .../java/org/bukkit/inventory/ItemStack.java | 2 +- .../io/papermc/paper/CraftGameEventTag.java | 2 +- .../papermc/paper/registry/PaperRegistries.java | 4 ++-- .../paper/registry/entry/RegistryEntryMeta.java | 2 +- .../paper/registry/event/RegistryEventMap.java | 2 +- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/NamespacedKey.java b/paper-api/src/main/java/org/bukkit/NamespacedKey.java index d71531c38..cb5782340 100644 --- a/paper-api/src/main/java/org/bukkit/NamespacedKey.java +++ b/paper-api/src/main/java/org/bukkit/NamespacedKey.java @@ -83,14 +83,12 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key, com.des * @see #NamespacedKey(Plugin, String) */ public NamespacedKey(@NotNull String namespace, @NotNull String key) { - Preconditions.checkArgument(namespace != null && isValidNamespace(namespace), "Invalid namespace. Must be [a-z0-9._-]: %s", namespace); - Preconditions.checkArgument(key != null && isValidKey(key), "Invalid key. Must be [a-z0-9/._-]: %s", key); - + Preconditions.checkArgument(namespace != null, "Namespace cannot be null"); + Preconditions.checkArgument(key != null, "Key cannot be null"); this.namespace = namespace; this.key = key; - String string = toString(); - Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation + this.validate(); } /** @@ -108,16 +106,17 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key, com.des public NamespacedKey(@NotNull Plugin plugin, @NotNull String key) { Preconditions.checkArgument(plugin != null, "Plugin cannot be null"); Preconditions.checkArgument(key != null, "Key cannot be null"); - this.namespace = plugin.getName().toLowerCase(Locale.ROOT); this.key = key.toLowerCase(Locale.ROOT); // Check validity after normalization + this.validate(); + } + + private void validate() { + Preconditions.checkArgument(this.namespace.length() + 1 + this.key.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters"); Preconditions.checkArgument(isValidNamespace(this.namespace), "Invalid namespace. Must be [a-z0-9._-]: %s", this.namespace); Preconditions.checkArgument(isValidKey(this.key), "Invalid key. Must be [a-z0-9/._-]: %s", this.key); - - String string = toString(); - Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation } @NotNull diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java index 09d999877..75e236ae2 100644 --- a/paper-api/src/main/java/org/bukkit/Registry.java +++ b/paper-api/src/main/java/org/bukkit/Registry.java @@ -64,7 +64,7 @@ public interface Registry extends Iterable { @SuppressWarnings("removal") @Deprecated(forRemoval = true, since = "1.21.4") private static Registry legacyRegistryFor(final Class clazz) { - return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), "No registry present for " + clazz.getSimpleName() + ". This is a bug."); + return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), () -> "No registry present for " + clazz.getSimpleName() + ". This is a bug."); } /** 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 5644b3501..dc50f83e9 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -57,7 +57,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat */ @org.jetbrains.annotations.Contract(value = "_, _ -> new", pure = true) public static @NotNull ItemStack of(final @NotNull Material type, final int amount) { - Preconditions.checkArgument(type.asItemType() != null, type + " isn't an item"); + Preconditions.checkArgument(type.asItemType() != null, "%s isn't an item", type); Preconditions.checkArgument(amount > 0, "amount must be greater than 0"); return java.util.Objects.requireNonNull(type.asItemType(), type + " is not an item").createItemStack(amount); // Paper - delegate } diff --git a/paper-server/src/main/java/io/papermc/paper/CraftGameEventTag.java b/paper-server/src/main/java/io/papermc/paper/CraftGameEventTag.java index 874c420e6..8a2662d4b 100644 --- a/paper-server/src/main/java/io/papermc/paper/CraftGameEventTag.java +++ b/paper-server/src/main/java/io/papermc/paper/CraftGameEventTag.java @@ -30,6 +30,6 @@ public class CraftGameEventTag extends CraftTag getValues() { - return getHandle().stream().map((nms) -> Objects.requireNonNull(GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(nms.value()))), nms + " is not a recognized game event")).collect(Collectors.toUnmodifiableSet()); + return getHandle().stream().map((nms) -> Objects.requireNonNull(GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(BuiltInRegistries.GAME_EVENT.getKey(nms.value()))), () -> nms + " is not a recognized game event")).collect(Collectors.toUnmodifiableSet()); } } 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 c0b17315a..d0e5ff93e 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 @@ -153,12 +153,12 @@ public final class PaperRegistries { @SuppressWarnings("unchecked") public static RegistryKey registryFromNms(final ResourceKey> registryResourceKey) { - return (RegistryKey) Objects.requireNonNull(BY_RESOURCE_KEY.get(registryResourceKey), registryResourceKey + " doesn't have an api RegistryKey").apiKey(); + return (RegistryKey) Objects.requireNonNull(BY_RESOURCE_KEY.get(registryResourceKey), () -> registryResourceKey + " doesn't have an api RegistryKey").apiKey(); } @SuppressWarnings("unchecked") public static ResourceKey> registryToNms(final RegistryKey registryKey) { - return (ResourceKey>) Objects.requireNonNull(BY_REGISTRY_KEY.get(registryKey), registryKey + " doesn't have an mc registry ResourceKey").mcKey(); + return (ResourceKey>) Objects.requireNonNull(BY_REGISTRY_KEY.get(registryKey), () -> registryKey + " doesn't have an mc registry ResourceKey").mcKey(); } public static TypedKey fromNms(final ResourceKey resourceKey) { diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java index 7cd152734..be3ec5863 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java @@ -60,7 +60,7 @@ public sealed interface RegistryEntryMeta permits RegistryEn ) implements ServerSide { // TODO remove Keyed public Craft { - Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), classToPreload + " should not be in the net.minecraft package as the class-to-preload"); + Preconditions.checkArgument(!classToPreload.getPackageName().startsWith("net.minecraft"), "%s should not be in the net.minecraft package as the class-to-preload", classToPreload); } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventMap.java b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventMap.java index bfcd0884d..2c662e895 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventMap.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventMap.java @@ -34,7 +34,7 @@ public final class RegistryEventMap { @SuppressWarnings("unchecked") public LifecycleEventType getEventType(final RegistryKey registryKey) { - return (LifecycleEventType) Objects.requireNonNull(this.eventTypes.get(registryKey), "No hook for " + registryKey); + return (LifecycleEventType) Objects.requireNonNull(this.eventTypes.get(registryKey), () -> "No hook for " + registryKey); } public boolean hasHandlers(final RegistryKey registryKey) { From 310f52293bd1877249bb3b1696cf8dbe1829db95 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Wed, 12 Mar 2025 12:50:40 +0100 Subject: [PATCH 184/203] Add unsupported config option and internal API to simplify remote item matching This is important for 1.21.5 servers/clients and non-Vanilla clients that may not be able to match 1.21.5 data hashes anymore --- .../server/level/ServerPlayer.java.patch | 9 ++++- .../AbstractContainerMenu.java.patch | 35 +++++++++++++++++++ .../ContainerSynchronizer.java.patch | 8 ++++- .../configuration/GlobalConfiguration.java | 2 ++ .../craftbukkit/entity/CraftPlayer.java | 18 ++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) 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 ebf5fb8da..a1ac8281e 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 @@ -10,7 +10,7 @@ @Nullable private Vec3 startingToFallPosition; @Nullable -@@ -258,6 +_,13 @@ +@@ -258,6 +_,20 @@ } } @@ -20,6 +20,13 @@ + 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) { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch index 6b7e7d70c..e9201236d 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/AbstractContainerMenu.java.patch @@ -72,6 +72,41 @@ } } } +@@ -243,7 +_,7 @@ + private void synchronizeSlotToRemote(int slotIndex, ItemStack stack, Supplier supplier) { + if (!this.suppressRemoteUpdates) { + ItemStack itemStack = this.remoteSlots.get(slotIndex); +- if (!ItemStack.matches(itemStack, stack)) { ++ if (!this.matchesRemote(itemStack, stack)) { // Paper - add flag to simplify remote matching logic + ItemStack itemStack1 = supplier.get(); + this.remoteSlots.set(slotIndex, itemStack1); + if (this.synchronizer != null) { +@@ -267,7 +_,7 @@ + + private void synchronizeCarriedToRemote() { + if (!this.suppressRemoteUpdates) { +- if (!ItemStack.matches(this.getCarried(), this.remoteCarried)) { ++ if (!this.matchesRemote(this.getCarried(), this.remoteCarried)) { // Paper - add flag to simplify remote matching logic + this.remoteCarried = this.getCarried().copy(); + if (this.synchronizer != null) { + this.synchronizer.sendCarriedChange(this, this.remoteCarried); +@@ -276,6 +_,16 @@ + } + } + ++ // Paper start - add flag to simplify remote matching logic ++ private boolean matchesRemote(final ItemStack stack, final ItemStack other) { ++ if (this.synchronizer != null && this.synchronizer.player() != null && this.synchronizer.player().getBukkitEntity().simplifyContainerDesyncCheck()) { ++ // Only check the item type and count ++ return stack == other || (stack.getCount() == other.getCount() && ItemStack.isSameItem(stack, other)); ++ } ++ return ItemStack.matches(stack, other); ++ } ++ // Paper end - add flag to simplify remote matching logic ++ + public void setRemoteSlot(int slot, ItemStack stack) { + this.remoteSlots.set(slot, stack.copy()); + } @@ -343,6 +_,7 @@ this.resetQuickCraft(); } 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 a5f19041a..e5eda2e88 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,9 +1,15 @@ --- a/net/minecraft/world/inventory/ContainerSynchronizer.java +++ b/net/minecraft/world/inventory/ContainerSynchronizer.java -@@ -11,4 +_,6 @@ +@@ -11,4 +_,12 @@ void sendCarriedChange(AbstractContainerMenu containerMenu, ItemStack stack); void sendDataChange(AbstractContainerMenu container, int id, int value); + + 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/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/paper-server/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java index a35391646..e3a7e6937 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 @@ -186,6 +186,8 @@ 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, 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 0e0abc233..5050f446e 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 @@ -8,6 +8,7 @@ import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Pair; import io.netty.buffer.Unpooled; import io.papermc.paper.FeatureHooks; +import io.papermc.paper.configuration.GlobalConfiguration; import io.papermc.paper.entity.LookAnchor; import io.papermc.paper.entity.PaperPlayerGiveResult; import io.papermc.paper.entity.PlayerGiveResult; @@ -225,6 +226,7 @@ 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) { @@ -3606,4 +3608,20 @@ 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; + } } From 6ea42025a49f232f47861c6ca943b0fc66b7effe Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Thu, 13 Mar 2025 12:41:03 +0100 Subject: [PATCH 185/203] Send all attributes on respawn (#12274) --- .../0016-Moonrise-optimisation-patches.patch | 12 ++++++------ .../minecraft/server/players/PlayerList.java.patch | 9 +++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 3c67eed11..c458f8f14 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -23751,7 +23751,7 @@ index 841a41485af62470d833aba578069b19a0bd1e8d..409c1134327bfcc338c3ac5e658a83cc // CraftBukkit start public boolean isDebugging() { diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java -index f8c81d795b19e73d56d6e0196c75e441ab4c2bef..97a294d2f5c1ddf0af7ffec3e1425eb329c5751b 100644 +index ac7bc193f7ea63cbbba73df49f54a17ef7cdec40..d2db6e3a4af13984b0a790fb38e83c253914a973 100644 --- a/net/minecraft/server/dedicated/DedicatedServer.java +++ b/net/minecraft/server/dedicated/DedicatedServer.java @@ -433,7 +433,33 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface @@ -26735,7 +26735,7 @@ index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7d if (!passengers.equals(this.lastPassengers)) { this.broadcastAndSend(new ClientboundSetPassengersPacket(this.entity)); // CraftBukkit diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 400b56657414177cd76a7b94c426dc7c886aa957..a275b17d0852d9d9bc850614713244e580ae81f1 100644 +index d1f235ebd835f58cf0c703c3a64d29825d98e183..080091efc19bc768bb9a660f366c42e831225505 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -170,7 +170,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; @@ -27976,10 +27976,10 @@ index 4eb040006f5d41b47e5ac9df5d9f19c4315d6343..7fa41dea184b01891f45d8e404bc1cba this.generatingStep = generatingStep; this.cache = cache; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 5d88b2790710a885957ffcffc02fb99c917123c5..7d1d4abfb04829d8c4722e326c6c6b8fb2ab91f4 100644 +index 7eebb494e38b57e81b4f92f0a96d3a4c610d86df..065f4c810439dde464529b54ae300ecfcb1c2c31 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -1312,7 +1312,7 @@ public abstract class PlayerList { +@@ -1317,7 +1317,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -27988,7 +27988,7 @@ index 5d88b2790710a885957ffcffc02fb99c917123c5..7d1d4abfb04829d8c4722e326c6c6b8f for (ServerLevel serverLevel : this.server.getAllLevels()) { if (serverLevel != null) { -@@ -1323,7 +1323,7 @@ public abstract class PlayerList { +@@ -1328,7 +1328,7 @@ public abstract class PlayerList { public void setSimulationDistance(int simulationDistance) { this.simulationDistance = simulationDistance; @@ -28372,7 +28372,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 994791a83ca6712db3e74ca9aba4bfcd95a0ec6d..1b54cf07616a10d93e9336dbd299ba5f09678a28 100644 +index 9b3b770f6986dd132da78fdc3626d334166ec52a..b2b61203438bb1fad1ee807729781718d2467155 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder; 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 9acc6fa13..43fe40f3c 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 @@ -931,13 +931,18 @@ } player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); -@@ -671,8 +_,16 @@ +@@ -671,8 +_,21 @@ public void sendAllPlayerInfo(ServerPlayer player) { player.inventoryMenu.sendAllDataToRemote(); - player.resetSentInfo(); + // entityplayer.resetSentInfo(); -+ player.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange ++ // Paper start - send all attributes ++ // needs to be done because the ServerPlayer instance is being reused on respawn instead of getting replaced like on vanilla ++ java.util.Collection syncableAttributes = player.getAttributes().getSyncableAttributes(); ++ player.getBukkitEntity().injectScaledMaxHealth(syncableAttributes, true); ++ player.connection.send(new net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket(player.getId(), syncableAttributes)); ++ // Paper end - send all attributes + player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected)); + // CraftBukkit start - from GameRules From 2d3a1385f13af450ab7a2d2e4d92f9d4793e87cb Mon Sep 17 00:00:00 2001 From: David Date: Mon, 17 Mar 2025 10:53:06 +0100 Subject: [PATCH 186/203] [ci skip] Refine recipe management API documentation. (#12287) * Refine recipe management API documentation. Improve Javadoc clarity for recipe addition methods, specifying client update behavior and stability considerations. Adjust formatting for better readability and consistency. * Fix typo in original javadoc --------- Co-authored-by: david --- paper-api/src/main/java/org/bukkit/Bukkit.java | 11 +++++++---- paper-api/src/main/java/org/bukkit/Server.java | 14 ++++++-------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/Bukkit.java b/paper-api/src/main/java/org/bukkit/Bukkit.java index a371da9d1..db47fe656 100644 --- a/paper-api/src/main/java/org/bukkit/Bukkit.java +++ b/paper-api/src/main/java/org/bukkit/Bukkit.java @@ -1117,20 +1117,24 @@ public final class Bukkit { /** * Adds a recipe to the crafting manager. + * Recipes added with this method won't be sent to the client automatically. + *

+ * Players still have to discover recipes via {@link Player#discoverRecipe(NamespacedKey)} + * before seeing them in their recipe book. * * @param recipe the recipe to add - * @return true if the recipe was added, false if it wasn't for some - * reason + * @return true if the recipe was added, false if it wasn't for some reason + * @see #addRecipe(Recipe, boolean) */ @Contract("null -> false") public static boolean addRecipe(@Nullable Recipe recipe) { return server.addRecipe(recipe); } - // Paper start - method to send recipes immediately /** * Adds a recipe to the crafting manager. * + * @apiNote resendRecipes is ignored at the moment for stability reasons, recipes will always be updated * @param recipe the recipe to add * @param resendRecipes true to update the client with the full set of recipes * @return true if the recipe was added, false if it wasn't for some reason @@ -1139,7 +1143,6 @@ public final class Bukkit { public static boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes) { return server.addRecipe(recipe, resendRecipes); } - // Paper end - method to send recipes immediately /** * Get a list of all recipes for a given item. The stack size is ignored diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index d7ebfcfc6..2eb72a31c 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -988,26 +988,24 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi public boolean dispatchCommand(@NotNull CommandSender sender, @NotNull String commandLine) throws CommandException; /** - * Adds a recipe to the crafting manager. Recipes added with - * this method won't be sent to the client automatically. Use - * {@link #updateRecipes()} or {@link #updateResources()} to - * update clients to new recipes added. + * Adds a recipe to the crafting manager. + * Recipes added with this method won't be sent to the client automatically. *

- * Player's still have to discover recipes via {@link Player#discoverRecipe(NamespacedKey)} + * Players still have to discover recipes via {@link Player#discoverRecipe(NamespacedKey)} * before seeing them in their recipe book. * * @param recipe the recipe to add - * @return true if the recipe was added, false if it wasn't for some - * reason + * @return true if the recipe was added, false if it wasn't for some reason * @see #addRecipe(Recipe, boolean) */ @Contract("null -> false") - public boolean addRecipe(@Nullable Recipe recipe); + boolean addRecipe(@Nullable Recipe recipe); // Paper start - method to send recipes immediately /** * Adds a recipe to the crafting manager. * + * @apiNote resendRecipes is ignored for now for stability reasons, recipes will always be updated * @param recipe the recipe to add * @param resendRecipes true to update the client with the full set of recipes * @return true if the recipe was added, false if it wasn't for some reason From aaaeb4e1e6477b0a6d586f70e739218ab68f59ec Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Mon, 17 Mar 2025 10:53:56 +0100 Subject: [PATCH 187/203] [ci skip] Make compilation logs actually readable (#12276) * [ci skip] Make compilation logs actually readable * Specifically disable deprecation and removal warnings instead --- build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle.kts b/build.gradle.kts index 9c20ed02f..fad7f3925 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,6 +38,7 @@ subprojects { options.encoding = Charsets.UTF_8.name() options.release = 21 options.isFork = true + options.compilerArgs.addAll(listOf("-Xlint:-deprecation", "-Xlint:-removal")) } tasks.withType { options.encoding = Charsets.UTF_8.name() From bb1beda67bfd94632815acc8ac5d68f5a8e3e410 Mon Sep 17 00:00:00 2001 From: Mart Date: Mon, 17 Mar 2025 05:54:49 -0400 Subject: [PATCH 188/203] feat: add event to wind charge explode (#12248) * feat: add event to wind charge explode * fix: use correct parameters * feat: allow setters to work * fix: use consts * Unify paper comments --------- Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com> --- .../windcharge/BreezeWindCharge.java.patch | 26 +++++++++++++++++++ .../windcharge/WindCharge.java.patch | 26 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/BreezeWindCharge.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/WindCharge.java.patch diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/BreezeWindCharge.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/BreezeWindCharge.java.patch new file mode 100644 index 000000000..4ea64e3a3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/BreezeWindCharge.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/entity/projectile/windcharge/BreezeWindCharge.java ++++ b/net/minecraft/world/entity/projectile/windcharge/BreezeWindCharge.java +@@ -20,6 +_,12 @@ + + @Override + public void explode(Vec3 pos) { ++ // Paper start - Fire event for WindCharge explosions ++ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, RADIUS, false); ++ if (event.isCancelled()) { ++ return; ++ } ++ // Paper end - Fire event for WindCharge explosions + this.level() + .explode( + this, +@@ -28,8 +_,8 @@ + pos.x(), + pos.y(), + pos.z(), +- 3.0F, +- false, ++ event.getRadius(), // Paper - Fire event for WindCharge explosions ++ event.getFire(), // Paper - Fire event for WindCharge explosions + Level.ExplosionInteraction.TRIGGER, + ParticleTypes.GUST_EMITTER_SMALL, + ParticleTypes.GUST_EMITTER_LARGE, diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/WindCharge.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/WindCharge.java.patch new file mode 100644 index 000000000..f01f24a98 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/windcharge/WindCharge.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/entity/projectile/windcharge/WindCharge.java ++++ b/net/minecraft/world/entity/projectile/windcharge/WindCharge.java +@@ -52,6 +_,12 @@ + + @Override + public void explode(Vec3 pos) { ++ // Paper start - Fire event for WindCharge explosions ++ org.bukkit.event.entity.ExplosionPrimeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExplosionPrimeEvent(this, RADIUS, false); ++ if (event.isCancelled()) { ++ return; ++ } ++ // Paper end - Fire event for WindCharge explosions + this.level() + .explode( + this, +@@ -60,8 +_,8 @@ + pos.x(), + pos.y(), + pos.z(), +- 1.2F, +- false, ++ event.getRadius(), // Paper - Fire event for WindCharge explosions ++ event.getFire(), // Paper - Fire event for WindCharge explosions + Level.ExplosionInteraction.TRIGGER, + ParticleTypes.GUST_EMITTER_SMALL, + ParticleTypes.GUST_EMITTER_LARGE, From 9f00461456480d626991cb39ca529273e7ce039e Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Fri, 21 Mar 2025 17:50:04 +0100 Subject: [PATCH 189/203] Update a whole lot of deprecated annotations --- .../destroystokyo/paper/NamespacedTag.java | 2 + .../event/entity/SkeletonHorseTrapEvent.java | 7 - .../event/player/IllegalPacketEvent.java | 2 +- .../PlayerClientOptionsChangeEvent.java | 14 - .../profile/ProfileWhitelistVerifyEvent.java | 6 - .../server/PaperServerListPingEvent.java | 12 - paper-api/src/main/java/org/bukkit/Art.java | 8 +- .../src/main/java/org/bukkit/Bukkit.java | 4 +- .../main/java/org/bukkit/ChunkSnapshot.java | 2 +- .../src/main/java/org/bukkit/Effect.java | 20 +- .../src/main/java/org/bukkit/Material.java | 932 +++++++++--------- .../src/main/java/org/bukkit/Server.java | 6 +- paper-api/src/main/java/org/bukkit/World.java | 5 +- .../src/main/java/org/bukkit/block/Block.java | 2 +- .../java/org/bukkit/block/BlockState.java | 4 +- .../src/main/java/org/bukkit/block/Skull.java | 4 +- .../org/bukkit/enchantments/Enchantment.java | 2 +- .../enchantments/EnchantmentTarget.java | 2 +- .../enchantments/EnchantmentWrapper.java | 2 +- .../java/org/bukkit/entity/AbstractArrow.java | 12 +- .../java/org/bukkit/entity/AbstractHorse.java | 8 +- .../org/bukkit/entity/AbstractSkeleton.java | 4 +- .../org/bukkit/entity/AreaEffectCloud.java | 4 +- .../main/java/org/bukkit/entity/Arrow.java | 4 +- .../src/main/java/org/bukkit/entity/Boat.java | 4 +- .../java/org/bukkit/entity/Endermite.java | 4 +- .../java/org/bukkit/entity/EntityType.java | 4 +- .../main/java/org/bukkit/entity/FishHook.java | 4 +- .../main/java/org/bukkit/entity/Horse.java | 4 +- .../org/bukkit/entity/LightningStrike.java | 6 +- .../main/java/org/bukkit/entity/Ocelot.java | 4 +- .../main/java/org/bukkit/entity/Zombie.java | 8 +- .../bukkit/event/block/BlockBurnEvent.java | 4 +- .../event/block/BlockCanBuildEvent.java | 10 +- .../bukkit/event/block/BlockCookEvent.java | 4 +- .../event/block/BlockMultiPlaceEvent.java | 5 +- .../bukkit/event/block/BlockPhysicsEvent.java | 5 +- .../event/block/BlockPistonExtendEvent.java | 6 +- .../bukkit/event/block/BlockPlaceEvent.java | 4 +- .../bukkit/event/block/SignChangeEvent.java | 8 +- .../event/entity/CreatureSpawnEvent.java | 2 +- .../entity/EntityCombustByBlockEvent.java | 4 +- .../entity/EntityCombustByEntityEvent.java | 4 +- .../event/entity/EntityCombustEvent.java | 4 +- .../entity/EntityDamageByEntityEvent.java | 4 +- .../bukkit/event/entity/EntityPlaceEvent.java | 4 +- .../event/entity/EntityPotionEffectEvent.java | 2 +- .../event/entity/EntityResurrectEvent.java | 4 +- .../event/entity/EntityShootBowEvent.java | 7 +- .../event/entity/EntityTargetEvent.java | 2 +- .../event/entity/EntityUnleashEvent.java | 4 +- .../bukkit/event/entity/ExpBottleEvent.java | 4 +- .../bukkit/event/entity/ItemSpawnEvent.java | 4 +- .../entity/LingeringPotionSplashEvent.java | 4 +- .../bukkit/event/entity/PlayerDeathEvent.java | 9 +- .../event/entity/PlayerLeashEntityEvent.java | 4 +- .../event/entity/PotionSplashEvent.java | 4 +- .../event/entity/ProjectileHitEvent.java | 11 +- .../event/entity/SheepDyeWoolEvent.java | 4 +- .../event/hanging/HangingPlaceEvent.java | 2 + .../event/inventory/FurnaceSmeltEvent.java | 7 +- .../inventory/FurnaceStartSmeltEvent.java | 4 +- .../event/inventory/InventoryAction.java | 2 +- .../player/AsyncPlayerPreLoginEvent.java | 8 +- .../event/player/PlayerAnimationEvent.java | 4 +- .../PlayerArmorStandManipulateEvent.java | 2 +- .../player/PlayerAttemptPickupItemEvent.java | 2 +- .../event/player/PlayerBedEnterEvent.java | 4 +- .../event/player/PlayerBucketEmptyEvent.java | 6 +- .../event/player/PlayerBucketEvent.java | 6 +- .../event/player/PlayerBucketFillEvent.java | 6 +- .../event/player/PlayerEditBookEvent.java | 2 +- .../player/PlayerGameModeChangeEvent.java | 4 +- .../event/player/PlayerHarvestBlockEvent.java | 4 +- .../event/player/PlayerItemConsumeEvent.java | 4 +- .../event/player/PlayerItemDamageEvent.java | 6 +- .../event/player/PlayerItemMendEvent.java | 7 +- .../bukkit/event/player/PlayerJoinEvent.java | 5 +- .../bukkit/event/player/PlayerKickEvent.java | 7 +- .../bukkit/event/player/PlayerLoginEvent.java | 6 +- .../event/player/PlayerPortalEvent.java | 4 +- .../event/player/PlayerPreLoginEvent.java | 4 +- .../bukkit/event/player/PlayerQuitEvent.java | 9 +- .../event/player/PlayerRespawnEvent.java | 8 +- .../event/player/PlayerRiptideEvent.java | 4 +- .../event/player/PlayerShearEntityEvent.java | 5 +- .../player/PlayerUnleashEntityEvent.java | 6 +- .../event/server/BroadcastMessageEvent.java | 8 +- .../event/server/ServerListPingEvent.java | 20 +- .../vehicle/VehicleBlockCollisionEvent.java | 4 +- .../event/weather/LightningStrikeEvent.java | 4 +- .../event/weather/ThunderChangeEvent.java | 5 +- .../event/weather/WeatherChangeEvent.java | 5 +- .../bukkit/event/world/PortalCreateEvent.java | 4 +- .../org/bukkit/inventory/FurnaceRecipe.java | 17 +- .../java/org/bukkit/inventory/ItemType.java | 2 +- .../org/bukkit/inventory/meta/MapMeta.java | 2 - .../org/bukkit/inventory/meta/PotionMeta.java | 4 +- .../meta/tags/CustomItemTagContainer.java | 2 +- .../meta/tags/ItemTagAdapterContext.java | 2 +- .../inventory/meta/tags/ItemTagType.java | 2 +- .../java/org/bukkit/loot/LootContext.java | 4 +- .../material/types/MushroomBlockTexture.java | 6 +- .../org/bukkit/plugin/PluginAwareness.java | 2 +- .../bukkit/plugin/PluginDescriptionFile.java | 2 +- .../org/bukkit/potion/PotionEffectType.java | 2 +- .../potion/PotionEffectTypeWrapper.java | 2 +- .../java/org/bukkit/potion/PotionType.java | 2 +- .../java/org/bukkit/scoreboard/Criterias.java | 2 +- .../main/java/org/bukkit/util/Consumer.java | 2 +- .../bukkit/materials/MaterialDataTest.java | 2 +- .../item/crafting/RecipeManager.java.patch | 8 + .../org/bukkit/craftbukkit/CraftServer.java | 5 - 113 files changed, 785 insertions(+), 710 deletions(-) diff --git a/paper-api/src/main/java/com/destroystokyo/paper/NamespacedTag.java b/paper-api/src/main/java/com/destroystokyo/paper/NamespacedTag.java index c976995a0..495b2d5f5 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/NamespacedTag.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/NamespacedTag.java @@ -5,6 +5,7 @@ import java.util.Locale; import java.util.UUID; import java.util.regex.Pattern; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -126,6 +127,7 @@ public final class NamespacedTag implements com.destroystokyo.paper.Namespaced { * @deprecated should never be used by plugins, for internal use only!! */ @Deprecated + @ApiStatus.Internal public static NamespacedTag randomKey() { return new NamespacedTag(BUKKIT, UUID.randomUUID().toString()); } diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java index a70f4972a..357cc548f 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/entity/SkeletonHorseTrapEvent.java @@ -1,6 +1,5 @@ package com.destroystokyo.paper.event.entity; -import com.google.common.collect.ImmutableList; import java.util.List; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.SkeletonHorse; @@ -21,12 +20,6 @@ public class SkeletonHorseTrapEvent extends EntityEvent implements Cancellable { private final List eligibleHumans; private boolean cancelled; - @Deprecated - @ApiStatus.Internal - public SkeletonHorseTrapEvent(final SkeletonHorse horse) { - this(horse, ImmutableList.of()); - } - @ApiStatus.Internal public SkeletonHorseTrapEvent(final SkeletonHorse horse, final List eligibleHumans) { super(horse); diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java index 446379282..46a84765e 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; /** * @deprecated Not used */ -@Deprecated(since = "1.16.4") +@Deprecated(since = "1.16.4", forRemoval = true) public class IllegalPacketEvent extends PlayerEvent { private static final HandlerList HANDLER_LIST = new HandlerList(); diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java index 5245955fb..6221601d0 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/player/PlayerClientOptionsChangeEvent.java @@ -30,20 +30,6 @@ public class PlayerClientOptionsChangeEvent extends PlayerEvent { private final boolean textFilteringEnabled; private final ParticleVisibility particleVisibility; - @Deprecated - public PlayerClientOptionsChangeEvent(final Player player, final String locale, final int viewDistance, final ChatVisibility chatVisibility, final boolean chatColors, final SkinParts skinParts, final MainHand mainHand) { - super(player); - this.locale = locale; - this.viewDistance = viewDistance; - this.chatVisibility = chatVisibility; - this.chatColors = chatColors; - this.skinparts = skinParts; - this.mainHand = mainHand; - this.allowsServerListings = false; - this.textFilteringEnabled = false; - this.particleVisibility = ParticleVisibility.ALL; - } - @ApiStatus.Internal public PlayerClientOptionsChangeEvent(final Player player, final Map, ?> options) { super(player); diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java index 901efb61f..45d198ebf 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java @@ -50,12 +50,6 @@ public class ProfileWhitelistVerifyEvent extends Event { private boolean whitelisted; private @Nullable Component kickMessage; - @Deprecated - @ApiStatus.Internal - public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable String kickMessage) { - this(profile, whitelistEnabled, whitelisted, isOp, kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage)); - } - @ApiStatus.Internal public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable Component kickMessage) { this.profile = profile; diff --git a/paper-api/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java b/paper-api/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java index f87e304f8..5ed6c6f8b 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java @@ -55,18 +55,6 @@ public class PaperServerListPingEvent extends ServerListPingEvent implements Can private boolean originalPlayerCount = true; private Object[] players; - @Deprecated - @ApiStatus.Internal - public PaperServerListPingEvent(@NotNull StatusClient client, @NotNull String motd, int numPlayers, int maxPlayers, - @NotNull String version, int protocolVersion, @Nullable CachedServerIcon favicon) { - super("", client.getAddress().getAddress(), motd, numPlayers, maxPlayers); - this.client = client; - this.numPlayers = numPlayers; - this.version = version; - this.protocolVersion = protocolVersion; - setServerIcon(favicon); - } - @ApiStatus.Internal public PaperServerListPingEvent(@NotNull StatusClient client, @NotNull net.kyori.adventure.text.Component motd, int numPlayers, int maxPlayers, @NotNull String version, int protocolVersion, @Nullable CachedServerIcon favicon) { diff --git a/paper-api/src/main/java/org/bukkit/Art.java b/paper-api/src/main/java/org/bukkit/Art.java index 82daa6941..bb8755c26 100644 --- a/paper-api/src/main/java/org/bukkit/Art.java +++ b/paper-api/src/main/java/org/bukkit/Art.java @@ -109,9 +109,9 @@ public interface Art extends OldEnum, Keyed { * Get the ID of this painting. * * @return The ID of this painting - * @deprecated Magic value + * @deprecated Magic value that is based on inconsistent, data-driven registry */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) int getId(); // Paper start - deprecate getKey @@ -162,9 +162,9 @@ public interface Art extends OldEnum, Keyed { * * @param id The ID * @return The painting - * @deprecated Magic value + * @deprecated Magic value that is based on inconsistent, data-driven registry */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) @Nullable static Art getById(int id) { for (Art art : Registry.ART) { diff --git a/paper-api/src/main/java/org/bukkit/Bukkit.java b/paper-api/src/main/java/org/bukkit/Bukkit.java index db47fe656..4eb723afa 100644 --- a/paper-api/src/main/java/org/bukkit/Bukkit.java +++ b/paper-api/src/main/java/org/bukkit/Bukkit.java @@ -930,7 +930,6 @@ public final class Bukkit { * @param id the id of the map to get * @return a map view if it exists, or null otherwise */ - // @Deprecated(since = "1.6.2") // Paper - Not a magic value @Nullable public static MapView getMap(int id) { return server.getMap(id); @@ -1392,7 +1391,7 @@ public final class Bukkit { * @return true if the server should send a preview, false otherwise * @deprecated chat previews have been removed */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) public static boolean shouldSendChatPreviews() { return server.shouldSendChatPreviews(); } @@ -1515,7 +1514,6 @@ public final class Bukkit { * @return an offline player * @see #getOfflinePlayer(java.util.UUID) */ - // @Deprecated(since = "1.7.5") // Paper @NotNull public static OfflinePlayer getOfflinePlayer(@NotNull String name) { return server.getOfflinePlayer(name); diff --git a/paper-api/src/main/java/org/bukkit/ChunkSnapshot.java b/paper-api/src/main/java/org/bukkit/ChunkSnapshot.java index 725d7944c..3370baab7 100644 --- a/paper-api/src/main/java/org/bukkit/ChunkSnapshot.java +++ b/paper-api/src/main/java/org/bukkit/ChunkSnapshot.java @@ -65,7 +65,7 @@ public interface ChunkSnapshot { * @return 0-15 * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) int getData(int x, int y, int z); /** diff --git a/paper-api/src/main/java/org/bukkit/Effect.java b/paper-api/src/main/java/org/bukkit/Effect.java index e013d83fb..089c485ce 100644 --- a/paper-api/src/main/java/org/bukkit/Effect.java +++ b/paper-api/src/main/java/org/bukkit/Effect.java @@ -27,70 +27,70 @@ public enum Effect { * @deprecated no longer exists * @see Sound#BLOCK_WOODEN_DOOR_OPEN */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) DOOR_TOGGLE(1006, Type.SOUND), /** * Sound of a door opening. * @deprecated no longer exists * @see Sound#BLOCK_IRON_DOOR_OPEN */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) IRON_DOOR_TOGGLE(1005, Type.SOUND), /** * Sound of a trapdoor opening. * @deprecated no longer exists * @see Sound#BLOCK_WOODEN_TRAPDOOR_OPEN */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) TRAPDOOR_TOGGLE(1007, Type.SOUND), /** * Sound of a door opening. * @deprecated no longer exists * @see Sound#BLOCK_IRON_TRAPDOOR_OPEN */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) IRON_TRAPDOOR_TOGGLE(1037, Type.SOUND), /** * Sound of a door opening. * @deprecated no longer exists * @see Sound#BLOCK_FENCE_GATE_OPEN */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) FENCE_GATE_TOGGLE(1008, Type.SOUND), /** * Sound of a door closing. * @deprecated no longer exists * @see Sound#BLOCK_WOODEN_DOOR_CLOSE */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) DOOR_CLOSE(1012, Type.SOUND), /** * Sound of a door closing. * @deprecated no longer exists * @see Sound#BLOCK_IRON_DOOR_CLOSE */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) IRON_DOOR_CLOSE(1011, Type.SOUND), /** * Sound of a trapdoor closing. * @deprecated no longer exists * @see Sound#BLOCK_WOODEN_TRAPDOOR_CLOSE */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) TRAPDOOR_CLOSE(1013, Type.SOUND), /** * Sound of a door closing. * @deprecated no longer exists * @see Sound#BLOCK_IRON_TRAPDOOR_CLOSE */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) IRON_TRAPDOOR_CLOSE(1036, Type.SOUND), /** * Sound of a door closing. * @deprecated no longer exists * @see Sound#BLOCK_FENCE_GATE_CLOSE */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) FENCE_GATE_CLOSE(1014, Type.SOUND), /** * Sound of fire being extinguished. diff --git a/paper-api/src/main/java/org/bukkit/Material.java b/paper-api/src/main/java/org/bukkit/Material.java index 9afafc00e..d43ce5dbf 100644 --- a/paper-api/src/main/java/org/bukkit/Material.java +++ b/paper-api/src/main/java/org/bukkit/Material.java @@ -3815,940 +3815,940 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla POTTED_OPEN_EYEBLOSSOM(24999), POTTED_CLOSED_EYEBLOSSOM(16694), // ----- Legacy Separator ----- - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_AIR(0, 0), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE(1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GRASS(2), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIRT(3), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COBBLESTONE(4), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD(5, org.bukkit.material.Wood.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SAPLING(6, org.bukkit.material.Sapling.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BEDROCK(7), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WATER(8, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STATIONARY_WATER(9, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LAVA(10, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STATIONARY_LAVA(11, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SAND(12), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GRAVEL(13), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_ORE(14), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_ORE(15), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COAL_ORE(16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LOG(17, org.bukkit.material.Tree.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEAVES(18, org.bukkit.material.Leaves.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPONGE(19), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GLASS(20), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LAPIS_ORE(21), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LAPIS_BLOCK(22), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DISPENSER(23, org.bukkit.material.Dispenser.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SANDSTONE(24, org.bukkit.material.Sandstone.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NOTE_BLOCK(25), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BED_BLOCK(26, org.bukkit.material.Bed.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_POWERED_RAIL(27, org.bukkit.material.PoweredRail.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DETECTOR_RAIL(28, org.bukkit.material.DetectorRail.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PISTON_STICKY_BASE(29, org.bukkit.material.PistonBaseMaterial.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WEB(30), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LONG_GRASS(31, org.bukkit.material.LongGrass.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DEAD_BUSH(32), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PISTON_BASE(33, org.bukkit.material.PistonBaseMaterial.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PISTON_EXTENSION(34, org.bukkit.material.PistonExtensionMaterial.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOL(35, org.bukkit.material.Wool.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PISTON_MOVING_PIECE(36), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_YELLOW_FLOWER(37), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_ROSE(38), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BROWN_MUSHROOM(39), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_MUSHROOM(40), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_BLOCK(41), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_BLOCK(42), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DOUBLE_STEP(43, org.bukkit.material.Step.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STEP(44, org.bukkit.material.Step.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BRICK(45), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TNT(46), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOOKSHELF(47), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MOSSY_COBBLESTONE(48), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_OBSIDIAN(49), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TORCH(50, org.bukkit.material.Torch.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FIRE(51), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MOB_SPAWNER(52), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_STAIRS(53, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHEST(54, org.bukkit.material.Chest.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_WIRE(55, org.bukkit.material.RedstoneWire.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_ORE(56), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_BLOCK(57), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WORKBENCH(58), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CROPS(59, org.bukkit.material.Crops.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SOIL(60, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FURNACE(61, org.bukkit.material.Furnace.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BURNING_FURNACE(62, org.bukkit.material.Furnace.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SIGN_POST(63, 64, org.bukkit.material.Sign.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOODEN_DOOR(64, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LADDER(65, org.bukkit.material.Ladder.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RAILS(66, org.bukkit.material.Rails.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COBBLESTONE_STAIRS(67, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WALL_SIGN(68, 64, org.bukkit.material.Sign.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEVER(69, org.bukkit.material.Lever.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_PLATE(70, org.bukkit.material.PressurePlate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_DOOR_BLOCK(71, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_PLATE(72, org.bukkit.material.PressurePlate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_ORE(73), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GLOWING_REDSTONE_ORE(74), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_TORCH_OFF(75, org.bukkit.material.RedstoneTorch.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_TORCH_ON(76, org.bukkit.material.RedstoneTorch.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_BUTTON(77, org.bukkit.material.Button.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SNOW(78), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ICE(79), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SNOW_BLOCK(80), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CACTUS(81, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CLAY(82), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SUGAR_CANE_BLOCK(83, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JUKEBOX(84), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FENCE(85), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PUMPKIN(86, org.bukkit.material.Pumpkin.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHERRACK(87), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SOUL_SAND(88), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GLOWSTONE(89), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PORTAL(90), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JACK_O_LANTERN(91, org.bukkit.material.Pumpkin.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CAKE_BLOCK(92, 64, org.bukkit.material.Cake.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIODE_BLOCK_OFF(93, org.bukkit.material.Diode.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIODE_BLOCK_ON(94, org.bukkit.material.Diode.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STAINED_GLASS(95), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TRAP_DOOR(96, org.bukkit.material.TrapDoor.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MONSTER_EGGS(97, org.bukkit.material.MonsterEggs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SMOOTH_BRICK(98, org.bukkit.material.SmoothBrick.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_HUGE_MUSHROOM_1(99, org.bukkit.material.Mushroom.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_HUGE_MUSHROOM_2(100, org.bukkit.material.Mushroom.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_FENCE(101), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_THIN_GLASS(102), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MELON_BLOCK(103), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PUMPKIN_STEM(104, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MELON_STEM(105, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_VINE(106, org.bukkit.material.Vine.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FENCE_GATE(107, org.bukkit.material.Gate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BRICK_STAIRS(108, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SMOOTH_STAIRS(109, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MYCEL(110), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WATER_LILY(111), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_BRICK(112), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_FENCE(113), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_BRICK_STAIRS(114, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_WARTS(115, org.bukkit.material.NetherWarts.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENCHANTMENT_TABLE(116), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BREWING_STAND(117, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CAULDRON(118, org.bukkit.material.Cauldron.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENDER_PORTAL(119), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENDER_PORTAL_FRAME(120), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENDER_STONE(121), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DRAGON_EGG(122), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_LAMP_OFF(123), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_LAMP_ON(124), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_DOUBLE_STEP(125, org.bukkit.material.Wood.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_STEP(126, org.bukkit.material.WoodenStep.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COCOA(127, org.bukkit.material.CocoaPlant.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SANDSTONE_STAIRS(128, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EMERALD_ORE(129), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENDER_CHEST(130, org.bukkit.material.EnderChest.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TRIPWIRE_HOOK(131, org.bukkit.material.TripwireHook.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TRIPWIRE(132, org.bukkit.material.Tripwire.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EMERALD_BLOCK(133), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPRUCE_WOOD_STAIRS(134, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BIRCH_WOOD_STAIRS(135, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JUNGLE_WOOD_STAIRS(136, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COMMAND(137, org.bukkit.material.Command.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BEACON(138), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COBBLE_WALL(139), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FLOWER_POT(140, org.bukkit.material.FlowerPot.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CARROT(141, org.bukkit.material.Crops.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_POTATO(142, org.bukkit.material.Crops.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_BUTTON(143, org.bukkit.material.Button.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SKULL(144, org.bukkit.material.Skull.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ANVIL(145), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TRAPPED_CHEST(146, org.bukkit.material.Chest.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_PLATE(147), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_PLATE(148), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_COMPARATOR_OFF(149, org.bukkit.material.Comparator.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_COMPARATOR_ON(150, org.bukkit.material.Comparator.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DAYLIGHT_DETECTOR(151), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_BLOCK(152), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_QUARTZ_ORE(153), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_HOPPER(154, org.bukkit.material.Hopper.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_QUARTZ_BLOCK(155), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_QUARTZ_STAIRS(156, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ACTIVATOR_RAIL(157, org.bukkit.material.PoweredRail.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DROPPER(158, org.bukkit.material.Dispenser.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STAINED_CLAY(159), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STAINED_GLASS_PANE(160), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEAVES_2(161, org.bukkit.material.Leaves.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LOG_2(162, org.bukkit.material.Tree.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ACACIA_STAIRS(163, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DARK_OAK_STAIRS(164, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SLIME_BLOCK(165), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BARRIER(166), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_TRAPDOOR(167, org.bukkit.material.TrapDoor.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PRISMARINE(168), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SEA_LANTERN(169), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_HAY_BLOCK(170), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CARPET(171), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_HARD_CLAY(172), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COAL_BLOCK(173), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PACKED_ICE(174), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DOUBLE_PLANT(175), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STANDING_BANNER(176, org.bukkit.material.Banner.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WALL_BANNER(177, org.bukkit.material.Banner.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DAYLIGHT_DETECTOR_INVERTED(178), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_SANDSTONE(179), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_SANDSTONE_STAIRS(180, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DOUBLE_STONE_SLAB2(181), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_SLAB2(182), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPRUCE_FENCE_GATE(183, org.bukkit.material.Gate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BIRCH_FENCE_GATE(184, org.bukkit.material.Gate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JUNGLE_FENCE_GATE(185, org.bukkit.material.Gate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DARK_OAK_FENCE_GATE(186, org.bukkit.material.Gate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ACACIA_FENCE_GATE(187, org.bukkit.material.Gate.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPRUCE_FENCE(188), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BIRCH_FENCE(189), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JUNGLE_FENCE(190), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DARK_OAK_FENCE(191), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ACACIA_FENCE(192), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPRUCE_DOOR(193, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BIRCH_DOOR(194, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JUNGLE_DOOR(195, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ACACIA_DOOR(196, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DARK_OAK_DOOR(197, org.bukkit.material.Door.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_END_ROD(198), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHORUS_PLANT(199), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHORUS_FLOWER(200), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPUR_BLOCK(201), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPUR_PILLAR(202), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPUR_STAIRS(203, org.bukkit.material.Stairs.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPUR_DOUBLE_SLAB(204), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPUR_SLAB(205), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_END_BRICKS(206), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BEETROOT_BLOCK(207, org.bukkit.material.Crops.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GRASS_PATH(208), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_END_GATEWAY(209), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COMMAND_REPEATING(210, org.bukkit.material.Command.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COMMAND_CHAIN(211, org.bukkit.material.Command.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FROSTED_ICE(212), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MAGMA(213), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_WART_BLOCK(214), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_NETHER_BRICK(215), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BONE_BLOCK(216), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STRUCTURE_VOID(217), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_OBSERVER(218, org.bukkit.material.Observer.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WHITE_SHULKER_BOX(219, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ORANGE_SHULKER_BOX(220, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MAGENTA_SHULKER_BOX(221, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LIGHT_BLUE_SHULKER_BOX(222, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_YELLOW_SHULKER_BOX(223, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LIME_SHULKER_BOX(224, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PINK_SHULKER_BOX(225, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GRAY_SHULKER_BOX(226, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SILVER_SHULKER_BOX(227, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CYAN_SHULKER_BOX(228, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPLE_SHULKER_BOX(229, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BLUE_SHULKER_BOX(230, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BROWN_SHULKER_BOX(231, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GREEN_SHULKER_BOX(232, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_SHULKER_BOX(233, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BLACK_SHULKER_BOX(234, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WHITE_GLAZED_TERRACOTTA(235), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ORANGE_GLAZED_TERRACOTTA(236), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MAGENTA_GLAZED_TERRACOTTA(237), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LIGHT_BLUE_GLAZED_TERRACOTTA(238), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_YELLOW_GLAZED_TERRACOTTA(239), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LIME_GLAZED_TERRACOTTA(240), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PINK_GLAZED_TERRACOTTA(241), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GRAY_GLAZED_TERRACOTTA(242), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SILVER_GLAZED_TERRACOTTA(243), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CYAN_GLAZED_TERRACOTTA(244), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PURPLE_GLAZED_TERRACOTTA(245), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BLUE_GLAZED_TERRACOTTA(246), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BROWN_GLAZED_TERRACOTTA(247), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GREEN_GLAZED_TERRACOTTA(248), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RED_GLAZED_TERRACOTTA(249), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BLACK_GLAZED_TERRACOTTA(250), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CONCRETE(251), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CONCRETE_POWDER(252), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STRUCTURE_BLOCK(255), // ----- Item Separator ----- - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_SPADE(256, 1, 250), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_PICKAXE(257, 1, 250), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_AXE(258, 1, 250), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FLINT_AND_STEEL(259, 1, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_APPLE(260), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOW(261, 1, 384), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ARROW(262), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COAL(263, org.bukkit.material.Coal.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND(264), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_INGOT(265), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_INGOT(266), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_SWORD(267, 1, 250), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_SWORD(268, 1, 59), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_SPADE(269, 1, 59), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_PICKAXE(270, 1, 59), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_AXE(271, 1, 59), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_SWORD(272, 1, 131), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_SPADE(273, 1, 131), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_PICKAXE(274, 1, 131), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_AXE(275, 1, 131), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_SWORD(276, 1, 1561), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_SPADE(277, 1, 1561), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_PICKAXE(278, 1, 1561), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_AXE(279, 1, 1561), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STICK(280), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOWL(281), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MUSHROOM_SOUP(282, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_SWORD(283, 1, 32), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_SPADE(284, 1, 32), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_PICKAXE(285, 1, 32), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_AXE(286, 1, 32), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STRING(287), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FEATHER(288), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SULPHUR(289), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_HOE(290, 1, 59), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STONE_HOE(291, 1, 131), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_HOE(292, 1, 250), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_HOE(293, 1, 1561), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_HOE(294, 1, 32), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SEEDS(295), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WHEAT(296), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BREAD(297), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEATHER_HELMET(298, 1, 55), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEATHER_CHESTPLATE(299, 1, 80), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEATHER_LEGGINGS(300, 1, 75), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEATHER_BOOTS(301, 1, 65), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHAINMAIL_HELMET(302, 1, 165), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHAINMAIL_CHESTPLATE(303, 1, 240), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHAINMAIL_LEGGINGS(304, 1, 225), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHAINMAIL_BOOTS(305, 1, 195), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_HELMET(306, 1, 165), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_CHESTPLATE(307, 1, 240), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_LEGGINGS(308, 1, 225), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_BOOTS(309, 1, 195), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_HELMET(310, 1, 363), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_CHESTPLATE(311, 1, 528), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_LEGGINGS(312, 1, 495), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_BOOTS(313, 1, 429), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_HELMET(314, 1, 77), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_CHESTPLATE(315, 1, 112), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_LEGGINGS(316, 1, 105), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_BOOTS(317, 1, 91), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FLINT(318), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PORK(319), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GRILLED_PORK(320), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PAINTING(321), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLDEN_APPLE(322), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SIGN(323, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WOOD_DOOR(324, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BUCKET(325, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WATER_BUCKET(326, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LAVA_BUCKET(327, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MINECART(328, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SADDLE(329, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_DOOR(330, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE(331), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SNOW_BALL(332, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOAT(333, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEATHER(334), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MILK_BUCKET(335, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CLAY_BRICK(336), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CLAY_BALL(337), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SUGAR_CANE(338), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PAPER(339), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOOK(340), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SLIME_BALL(341), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_STORAGE_MINECART(342, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_POWERED_MINECART(343, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EGG(344, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COMPASS(345), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FISHING_ROD(346, 1, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WATCH(347), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GLOWSTONE_DUST(348), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RAW_FISH(349), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COOKED_FISH(350), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_INK_SACK(351, org.bukkit.material.Dye.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BONE(352), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SUGAR(353), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CAKE(354, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BED(355, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIODE(356), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COOKIE(357), /** * @see org.bukkit.map.MapView */ - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MAP(358, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SHEARS(359, 1, 238), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MELON(360), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PUMPKIN_SEEDS(361), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MELON_SEEDS(362), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RAW_BEEF(363), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COOKED_BEEF(364), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RAW_CHICKEN(365), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COOKED_CHICKEN(366), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ROTTEN_FLESH(367), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENDER_PEARL(368, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BLAZE_ROD(369), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GHAST_TEAR(370), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_NUGGET(371), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_STALK(372), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_POTION(373, 1, org.bukkit.material.MaterialData.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GLASS_BOTTLE(374), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPIDER_EYE(375), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FERMENTED_SPIDER_EYE(376), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BLAZE_POWDER(377), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MAGMA_CREAM(378), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BREWING_STAND_ITEM(379), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CAULDRON_ITEM(380), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EYE_OF_ENDER(381), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPECKLED_MELON(382), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MONSTER_EGG(383, 64, org.bukkit.material.SpawnEgg.class), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EXP_BOTTLE(384, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FIREBALL(385, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOOK_AND_QUILL(386, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_WRITTEN_BOOK(387, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EMERALD(388, 64), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ITEM_FRAME(389), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FLOWER_POT_ITEM(390), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CARROT_ITEM(391), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_POTATO_ITEM(392), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BAKED_POTATO(393), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_POISONOUS_POTATO(394), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EMPTY_MAP(395), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLDEN_CARROT(396), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SKULL_ITEM(397), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CARROT_STICK(398, 1, 25), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_STAR(399), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PUMPKIN_PIE(400), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FIREWORK(401), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_FIREWORK_CHARGE(402), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ENCHANTED_BOOK(403, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_REDSTONE_COMPARATOR(404), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NETHER_BRICK_ITEM(405), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_QUARTZ(406), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_EXPLOSIVE_MINECART(407, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_HOPPER_MINECART(408, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PRISMARINE_SHARD(409), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_PRISMARINE_CRYSTALS(410), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RABBIT(411), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COOKED_RABBIT(412), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RABBIT_STEW(413, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RABBIT_FOOT(414), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RABBIT_HIDE(415), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ARMOR_STAND(416, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_BARDING(417, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_BARDING(418, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DIAMOND_BARDING(419, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LEASH(420), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_NAME_TAG(421), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COMMAND_MINECART(422, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_MUTTON(423), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_COOKED_MUTTON(424), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BANNER(425, 16), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_END_CRYSTAL(426), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPRUCE_DOOR_ITEM(427), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BIRCH_DOOR_ITEM(428), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_JUNGLE_DOOR_ITEM(429), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ACACIA_DOOR_ITEM(430), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DARK_OAK_DOOR_ITEM(431), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHORUS_FRUIT(432), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_CHORUS_FRUIT_POPPED(433), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BEETROOT(434), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BEETROOT_SEEDS(435), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BEETROOT_SOUP(436, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_DRAGONS_BREATH(437), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPLASH_POTION(438, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SPECTRAL_ARROW(439), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TIPPED_ARROW(440), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_LINGERING_POTION(441, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SHIELD(442, 1, 336), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_ELYTRA(443, 1, 431), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOAT_SPRUCE(444, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOAT_BIRCH(445, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOAT_JUNGLE(446, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOAT_ACACIA(447, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_BOAT_DARK_OAK(448, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_TOTEM(449, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_SHULKER_SHELL(450), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_IRON_NUGGET(452), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_KNOWLEDGE_BOOK(453, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GOLD_RECORD(2256, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_GREEN_RECORD(2257, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_3(2258, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_4(2259, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_5(2260, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_6(2261, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_7(2262, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_8(2263, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_9(2264, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_10(2265, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_11(2266, 1), - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) LEGACY_RECORD_12(2267, 1), ; // - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) public static final String LEGACY_PREFIX = "LEGACY_"; private final int id; @@ -4909,7 +4909,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla * * @return legacy status */ - // @Deprecated(since = "1.13") // Paper - this is useful, don't deprecate + // @Deprecated(since = "1.13", forRemoval = true) // Paper - this is useful, don't deprecate public boolean isLegacy() { return legacy; } @@ -5167,7 +5167,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla * @deprecated currently does not have an implementation which is well * linked to the underlying server. Contributions welcome. */ - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) public boolean isTransparent() { if (!isBlock()) { return false; diff --git a/paper-api/src/main/java/org/bukkit/Server.java b/paper-api/src/main/java/org/bukkit/Server.java index 2eb72a31c..0c1f3053e 100644 --- a/paper-api/src/main/java/org/bukkit/Server.java +++ b/paper-api/src/main/java/org/bukkit/Server.java @@ -1231,8 +1231,10 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi * @return true if the server should send a preview, false otherwise * @deprecated chat previews have been removed */ - @Deprecated(since = "1.19.3") - public boolean shouldSendChatPreviews(); + @Deprecated(since = "1.19.3", forRemoval = true) + default boolean shouldSendChatPreviews() { + return false; + } /** * Gets whether the server only allow players with Mojang-signed public key diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index 015d852d5..96120ce0e 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -494,7 +494,6 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @return Whether the chunk was actually refreshed * */ - // @Deprecated(since = "1.8") // Paper public boolean refreshChunk(int x, int z); /** @@ -2478,7 +2477,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @deprecated Use {@link #spawn(Location, Class, Consumer)} (or a variation thereof) in combination with {@link FallingBlock#setBlockData(BlockData)} */ @NotNull - @Deprecated(since = "1.20.2") // Paper + @Deprecated(since = "1.20.2", forRemoval = true) public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull MaterialData data) throws IllegalArgumentException; /** @@ -2513,7 +2512,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * Material} are null or {@link Material} is not a block * @deprecated Magic value. Use {@link #spawn(Location, Class, Consumer)} (or a variation thereof) in combination with {@link FallingBlock#setBlockData(BlockData)} */ - @Deprecated(since = "1.7.5") + @Deprecated(since = "1.7.5", forRemoval = true) @NotNull public FallingBlock spawnFallingBlock(@NotNull Location location, @NotNull Material material, byte data) throws IllegalArgumentException; diff --git a/paper-api/src/main/java/org/bukkit/block/Block.java b/paper-api/src/main/java/org/bukkit/block/Block.java index b703ad820..c6e9ca88e 100644 --- a/paper-api/src/main/java/org/bukkit/block/Block.java +++ b/paper-api/src/main/java/org/bukkit/block/Block.java @@ -40,7 +40,7 @@ public interface Block extends Metadatable, Translatable, net.kyori.adventure.tr * @return block specific metadata * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) byte getData(); /** diff --git a/paper-api/src/main/java/org/bukkit/block/BlockState.java b/paper-api/src/main/java/org/bukkit/block/BlockState.java index 3bcdb02f8..2c430a7fb 100644 --- a/paper-api/src/main/java/org/bukkit/block/BlockState.java +++ b/paper-api/src/main/java/org/bukkit/block/BlockState.java @@ -225,14 +225,14 @@ public interface BlockState extends Metadatable { * @return The data as a raw byte. * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) public byte getRawData(); /** * @param data The new data value for the block. * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) public void setRawData(byte data); /** diff --git a/paper-api/src/main/java/org/bukkit/block/Skull.java b/paper-api/src/main/java/org/bukkit/block/Skull.java index d6add557e..d73137292 100644 --- a/paper-api/src/main/java/org/bukkit/block/Skull.java +++ b/paper-api/src/main/java/org/bukkit/block/Skull.java @@ -155,7 +155,7 @@ public interface Skull extends TileState { * @return the type of skull * @deprecated check {@link Material} instead */ - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) @NotNull public SkullType getSkullType(); @@ -165,7 +165,7 @@ public interface Skull extends TileState { * @param skullType the type of skull * @deprecated check {@link Material} instead */ - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) @Contract("_ -> fail") public void setSkullType(SkullType skullType); } diff --git a/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java b/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java index 288123c31..4a6c44c65 100644 --- a/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java +++ b/paper-api/src/main/java/org/bukkit/enchantments/Enchantment.java @@ -241,7 +241,7 @@ public abstract class Enchantment implements Keyed, Translatable, net.kyori.adve * @deprecated enchantments are badly named, use {@link #getKey()}. */ @NotNull - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) public abstract String getName(); /** diff --git a/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java index 6fcc15d58..fc71bc086 100644 --- a/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java +++ b/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java @@ -13,7 +13,7 @@ public enum EnchantmentTarget { * * @deprecated this target no longer exists in Vanilla */ - @Deprecated(since = "1.16.1") + @Deprecated(since = "1.16.1", forRemoval = true) ALL { @Override public boolean includes(@NotNull Material item) { diff --git a/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java b/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java index ca3b2f9be..74b0be66e 100644 --- a/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java +++ b/paper-api/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull; * A simple wrapper for ease of selecting {@link Enchantment}s * @deprecated only for backwards compatibility, EnchantmentWrapper is no longer used. */ -@Deprecated(since = "1.20.3") +@Deprecated(since = "1.20.3", forRemoval = true) public abstract class EnchantmentWrapper extends Enchantment { protected EnchantmentWrapper() { } diff --git a/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java b/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java index 1c2c9ed0d..945e81977 100644 --- a/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java +++ b/paper-api/src/main/java/org/bukkit/entity/AbstractArrow.java @@ -20,9 +20,9 @@ public interface AbstractArrow extends Projectile { * * @return the knockback strength value * @see #getWeapon() - * @deprecated a function of the firing weapon + * @deprecated moved to being a function of the firing weapon, always returns 0 here */ - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public int getKnockbackStrength(); /** @@ -30,9 +30,9 @@ public interface AbstractArrow extends Projectile { * * @param knockbackStrength the knockback strength value * @see #setWeapon(org.bukkit.inventory.ItemStack) - * @deprecated a function of the firing weapon + * @deprecated moved to being a function of the firing weapon, does nothing here */ - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public void setKnockbackStrength(int knockbackStrength); /** @@ -145,9 +145,9 @@ public interface AbstractArrow extends Projectile { * * @param shotFromCrossbow if shot from a crossbow * @see #setWeapon(org.bukkit.inventory.ItemStack) - * @deprecated a function of the firing weapon instead + * @deprecated a function of the firing weapon instead, this method does nothing */ - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public void setShotFromCrossbow(boolean shotFromCrossbow); /** diff --git a/paper-api/src/main/java/org/bukkit/entity/AbstractHorse.java b/paper-api/src/main/java/org/bukkit/entity/AbstractHorse.java index 2e9d6e602..38967c57a 100644 --- a/paper-api/src/main/java/org/bukkit/entity/AbstractHorse.java +++ b/paper-api/src/main/java/org/bukkit/entity/AbstractHorse.java @@ -20,7 +20,7 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable { * @return a {@link Horse.Variant} representing the horse's variant * @deprecated different variants are different classes */ - @Deprecated(since = "1.11") + @Deprecated(since = "1.11", forRemoval = true) @NotNull public Horse.Variant getVariant(); @@ -28,7 +28,7 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable { * @param variant variant * @deprecated you are required to spawn a different entity */ - @Deprecated(since = "1.11") + @Deprecated(since = "1.11", forRemoval = true) @Contract("_ -> fail") public void setVariant(Horse.Variant variant); @@ -108,7 +108,7 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable { * @return true if eating hay * @deprecated use {@link #isEatingGrass()}, this name is incorrect */ - @Deprecated // Paper - Horse API + @Deprecated(forRemoval = true) boolean isEatingHaystack(); /** @@ -117,7 +117,7 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable { * @param eatingHaystack new hay grazing status * @deprecated use {@link #setEatingGrass(boolean)}, this name is incorrect */ - @Deprecated // Paper - Horse API + @Deprecated(forRemoval = true) void setEatingHaystack(boolean eatingHaystack); @NotNull diff --git a/paper-api/src/main/java/org/bukkit/entity/AbstractSkeleton.java b/paper-api/src/main/java/org/bukkit/entity/AbstractSkeleton.java index db101017a..fbd0e7681 100644 --- a/paper-api/src/main/java/org/bukkit/entity/AbstractSkeleton.java +++ b/paper-api/src/main/java/org/bukkit/entity/AbstractSkeleton.java @@ -21,7 +21,7 @@ public interface AbstractSkeleton extends Monster, com.destroystokyo.paper.entit * @return Current type * @deprecated should check what class instance this is. */ - @Deprecated(since = "1.17") + @Deprecated(since = "1.17", forRemoval = true) @NotNull public Skeleton.SkeletonType getSkeletonType(); @@ -29,7 +29,7 @@ public interface AbstractSkeleton extends Monster, com.destroystokyo.paper.entit * @param type type * @deprecated Must spawn a new subtype variant */ - @Deprecated(since = "1.17") + @Deprecated(since = "1.17", forRemoval = true) @Contract("_ -> fail") public void setSkeletonType(Skeleton.SkeletonType type); diff --git a/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java b/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java index c4b3ab4b9..e36b62012 100644 --- a/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java +++ b/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java @@ -152,7 +152,7 @@ public interface AreaEffectCloud extends Entity { * @param data PotionData to set the base potion state to * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead. */ - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) void setBasePotionData(@Nullable PotionData data); /** @@ -162,7 +162,7 @@ public interface AreaEffectCloud extends Entity { * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead. */ @Nullable - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) PotionData getBasePotionData(); /** diff --git a/paper-api/src/main/java/org/bukkit/entity/Arrow.java b/paper-api/src/main/java/org/bukkit/entity/Arrow.java index 38e6a8dbb..2ed441e20 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Arrow.java +++ b/paper-api/src/main/java/org/bukkit/entity/Arrow.java @@ -17,7 +17,7 @@ public interface Arrow extends AbstractArrow { * @param data PotionData to set the base potion state to * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead. */ - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) void setBasePotionData(@Nullable PotionData data); /** @@ -27,7 +27,7 @@ public interface Arrow extends AbstractArrow { * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead. */ @Nullable - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) PotionData getBasePotionData(); /** diff --git a/paper-api/src/main/java/org/bukkit/entity/Boat.java b/paper-api/src/main/java/org/bukkit/entity/Boat.java index aedfdf41d..1c977e2b1 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Boat.java +++ b/paper-api/src/main/java/org/bukkit/entity/Boat.java @@ -15,7 +15,7 @@ public interface Boat extends Vehicle, io.papermc.paper.entity.Leashable { // Pa * @return the wood type * @deprecated deprecated in favor of {@link #getBoatType()} */ - @Deprecated(since = "1.19") + @Deprecated(since = "1.19", forRemoval = true) @NotNull TreeSpecies getWoodType(); @@ -25,7 +25,7 @@ public interface Boat extends Vehicle, io.papermc.paper.entity.Leashable { // Pa * @param species the new wood type * @deprecated deprecated in favor of {@link #setBoatType(Type)} */ - @Deprecated(since = "1.19") + @Deprecated(since = "1.19", forRemoval = true) void setWoodType(@NotNull TreeSpecies species); /** diff --git a/paper-api/src/main/java/org/bukkit/entity/Endermite.java b/paper-api/src/main/java/org/bukkit/entity/Endermite.java index 7b379fb21..332c55fd6 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Endermite.java +++ b/paper-api/src/main/java/org/bukkit/entity/Endermite.java @@ -10,7 +10,7 @@ public interface Endermite extends Monster { * @return player spawned status * @deprecated this functionality no longer exists */ - @Deprecated(since = "1.17") + @Deprecated(since = "1.17", forRemoval = true) boolean isPlayerSpawned(); /** @@ -21,7 +21,7 @@ public interface Endermite extends Monster { * @param playerSpawned player spawned status * @deprecated this functionality no longer exists */ - @Deprecated(since = "1.17") + @Deprecated(since = "1.17", forRemoval = true) void setPlayerSpawned(boolean playerSpawned); // Paper start /** diff --git a/paper-api/src/main/java/org/bukkit/entity/EntityType.java b/paper-api/src/main/java/org/bukkit/entity/EntityType.java index 29d225116..73e47089d 100644 --- a/paper-api/src/main/java/org/bukkit/entity/EntityType.java +++ b/paper-api/src/main/java/org/bukkit/entity/EntityType.java @@ -407,7 +407,7 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans * @return the raw type id * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) public short getTypeId() { return typeId; } @@ -436,7 +436,7 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans * @return the matching entity type or null * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) @Nullable public static EntityType fromId(int id) { if (id > Short.MAX_VALUE) { 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 c28e78aa2..470443e3e 100644 --- a/paper-api/src/main/java/org/bukkit/entity/FishHook.java +++ b/paper-api/src/main/java/org/bukkit/entity/FishHook.java @@ -208,7 +208,7 @@ public interface FishHook extends Projectile { * @return chance the bite chance * @deprecated has no effect in newer Minecraft versions */ - @Deprecated(since = "1.9.2") + @Deprecated(since = "1.9.2", forRemoval = true) public double getBiteChance(); /** @@ -222,7 +222,7 @@ public interface FishHook extends Projectile { * and 1 * @deprecated has no effect in newer Minecraft versions */ - @Deprecated(since = "1.9.2") + @Deprecated(since = "1.9.2", forRemoval = true) public void setBiteChance(double chance) throws IllegalArgumentException; /** diff --git a/paper-api/src/main/java/org/bukkit/entity/Horse.java b/paper-api/src/main/java/org/bukkit/entity/Horse.java index ea2df6144..f2089ce6e 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Horse.java +++ b/paper-api/src/main/java/org/bukkit/entity/Horse.java @@ -154,14 +154,14 @@ public interface Horse extends AbstractHorse { * @return carrying chest status * @deprecated see {@link ChestedHorse} */ - @Deprecated(since = "1.11") + @Deprecated(since = "1.11", forRemoval = true) public boolean isCarryingChest(); /** * @param chest chest * @deprecated see {@link ChestedHorse} */ - @Deprecated(since = "1.11") + @Deprecated(since = "1.11", forRemoval = true) public void setCarryingChest(boolean chest); @NotNull diff --git a/paper-api/src/main/java/org/bukkit/entity/LightningStrike.java b/paper-api/src/main/java/org/bukkit/entity/LightningStrike.java index fb2a9b10b..ecbfa1294 100644 --- a/paper-api/src/main/java/org/bukkit/entity/LightningStrike.java +++ b/paper-api/src/main/java/org/bukkit/entity/LightningStrike.java @@ -91,7 +91,7 @@ public interface LightningStrike extends Entity { /** * @deprecated Unsupported api */ - @Deprecated // Paper + @Deprecated(forRemoval = true) public class Spigot extends Entity.Spigot { /** @@ -100,7 +100,7 @@ public interface LightningStrike extends Entity { * @return whether the strike is silent. * @deprecated sound is now client side and cannot be removed */ - @Deprecated(since = "1.20.4") + @Deprecated(since = "1.20.4", forRemoval = true) public boolean isSilent() { throw new UnsupportedOperationException("Not supported yet."); } @@ -111,7 +111,7 @@ public interface LightningStrike extends Entity { */ @NotNull @Override - @Deprecated // Paper + @Deprecated(forRemoval = true) Spigot spigot(); // Spigot end diff --git a/paper-api/src/main/java/org/bukkit/entity/Ocelot.java b/paper-api/src/main/java/org/bukkit/entity/Ocelot.java index ce22fa260..3aa04671f 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Ocelot.java +++ b/paper-api/src/main/java/org/bukkit/entity/Ocelot.java @@ -73,7 +73,7 @@ public interface Ocelot extends Animals { * @return Type ID. * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) public int getId() { return id; } @@ -85,7 +85,7 @@ public interface Ocelot extends Animals { * @return Resulting type, or null if not found. * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) @Nullable public static Type getType(int id) { return (id >= types.length) ? null : types[id]; 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 5b9e1af02..65e870c75 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Zombie.java +++ b/paper-api/src/main/java/org/bukkit/entity/Zombie.java @@ -32,14 +32,14 @@ public interface Zombie extends Monster, Ageable { * @return Whether the zombie is a villager * @deprecated check if instanceof {@link ZombieVillager}. */ - @Deprecated(since = "1.10.2") + @Deprecated(since = "1.10.2", forRemoval = true) public boolean isVillager(); /** * @param flag flag * @deprecated must spawn {@link ZombieVillager}. */ - @Deprecated(since = "1.9") + @Deprecated(since = "1.9", forRemoval = true) @Contract("_ -> fail") public void setVillager(boolean flag); @@ -47,7 +47,7 @@ public interface Zombie extends Monster, Ageable { * @param profession profession * @see ZombieVillager#getVillagerProfession() */ - @Deprecated(since = "1.10.2") + @Deprecated(since = "1.10.2", forRemoval = true) @Contract("_ -> fail") public void setVillagerProfession(Villager.Profession profession); @@ -55,7 +55,7 @@ public interface Zombie extends Monster, Ageable { * @return profession * @see ZombieVillager#getVillagerProfession() */ - @Deprecated(since = "1.10.2") + @Deprecated(since = "1.10.2", forRemoval = true) @Nullable @Contract("-> null") public Villager.Profession getVillagerProfession(); diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockBurnEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockBurnEvent.java index 0b1737bcc..056f6ddb3 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockBurnEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockBurnEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.block; import org.bukkit.block.Block; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,11 +18,12 @@ public class BlockBurnEvent extends BlockEvent implements Cancellable { private boolean cancelled; private final Block ignitingBlock; - @Deprecated(since = "1.11.2") + @Deprecated(since = "1.11.2", forRemoval = true) public BlockBurnEvent(@NotNull final Block block) { this(block, null); } + @ApiStatus.Internal public BlockBurnEvent(@NotNull final Block block, @Nullable final Block ignitingBlock) { super(block); this.ignitingBlock = ignitingBlock; diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java index f5923049b..7969e15bb 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java @@ -5,6 +5,7 @@ import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,7 +28,7 @@ public class BlockCanBuildEvent extends BlockEvent { private final Player player; private final org.bukkit.inventory.EquipmentSlot hand; // Paper - expose hand - @Deprecated(since = "1.13.2") + @Deprecated(since = "1.13.2", forRemoval = true) public BlockCanBuildEvent(@NotNull final Block block, @NotNull final BlockData type, final boolean canBuild) { this(block, null, type, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); // Paper - expose hand } @@ -38,12 +39,13 @@ public class BlockCanBuildEvent extends BlockEvent { * @param type the id of the block to place * @param canBuild whether we can build */ - @java.lang.Deprecated // Paper - @io.papermc.paper.annotation.DoNotUse // Paper + @Deprecated(forRemoval = true) + @io.papermc.paper.annotation.DoNotUse public BlockCanBuildEvent(@NotNull final Block block, @Nullable final Player player, @NotNull final BlockData type, final boolean canBuild) { this(block, player, type, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); // Paper start - expose hand } - @org.jetbrains.annotations.ApiStatus.Internal + + @ApiStatus.Internal public BlockCanBuildEvent(@NotNull final Block block, @Nullable final Player player, @NotNull final BlockData type, final boolean canBuild, @NotNull final org.bukkit.inventory.EquipmentSlot hand) { // Paper end - expose hand super(block); this.player = player; diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockCookEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockCookEvent.java index a3f1c9cb3..4a4bc9df2 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockCookEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockCookEvent.java @@ -4,6 +4,7 @@ import org.bukkit.block.Block; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -16,12 +17,13 @@ public class BlockCookEvent extends BlockEvent implements Cancellable { private boolean cancelled; private final org.bukkit.inventory.CookingRecipe recipe; // Paper - @Deprecated // Paper + @Deprecated(forRemoval = true) public BlockCookEvent(@NotNull final Block block, @NotNull final ItemStack source, @NotNull final ItemStack result) { // Paper start this(block, source, result, null); } + @ApiStatus.Internal public BlockCookEvent(@NotNull final Block block, @NotNull final ItemStack source, @NotNull final ItemStack result, @org.jetbrains.annotations.Nullable org.bukkit.inventory.CookingRecipe recipe) { // Paper end super(block); diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java index 7ca2b1b32..72499d0ea 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java @@ -6,6 +6,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -18,13 +19,13 @@ import org.jetbrains.annotations.NotNull; public class BlockMultiPlaceEvent extends BlockPlaceEvent { private final List states; - @Deprecated // Paper + @Deprecated(forRemoval = true) public BlockMultiPlaceEvent(@NotNull List states, @NotNull Block clicked, @NotNull ItemStack itemInHand, @NotNull Player thePlayer, boolean canBuild) { // Paper start - add hand to BlockMultiPlaceEvent this(states, clicked, itemInHand, thePlayer, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); } - + @ApiStatus.Internal public BlockMultiPlaceEvent(@NotNull List states, @NotNull Block clicked, @NotNull ItemStack itemInHand, @NotNull Player thePlayer, boolean canBuild, @NotNull org.bukkit.inventory.EquipmentSlot hand) { super(states.get(0).getBlock(), states.get(0), clicked, itemInHand, thePlayer, canBuild, hand); this.states = ImmutableList.copyOf(states); diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java index b23686d2e..0d52c6d04 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java @@ -5,6 +5,7 @@ import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -33,16 +34,18 @@ public class BlockPhysicsEvent extends BlockEvent implements Cancellable { private boolean cancel = false; // Paper start - Legacy constructor, use #BlockPhysicsEvent(Block, BlockData, Block) - @Deprecated + @Deprecated(forRemoval = true) public BlockPhysicsEvent(final Block block, final BlockData changed, final int sourceX, final int sourceY, final int sourceZ) { this(block, changed, block.getWorld().getBlockAt(sourceX, sourceY, sourceZ)); } // Paper end + @ApiStatus.Internal public BlockPhysicsEvent(@NotNull final Block block, @NotNull final BlockData changed) { this(block, changed, block); } + @ApiStatus.Internal public BlockPhysicsEvent(@NotNull final Block block, @NotNull final BlockData changed, @NotNull final Block sourceBlock) { super(block); this.changed = changed; diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java index 6caecd53d..202f0a556 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java @@ -6,6 +6,7 @@ import java.util.List; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -16,13 +17,14 @@ public class BlockPistonExtendEvent extends BlockPistonEvent { private final int length; private List blocks; - @Deprecated(since = "1.8") + @Deprecated(since = "1.8", forRemoval = true) public BlockPistonExtendEvent(@NotNull final Block block, final int length, @NotNull final BlockFace direction) { super(block, direction); this.length = length; } + @ApiStatus.Internal public BlockPistonExtendEvent(@NotNull final Block block, @NotNull final List blocks, @NotNull final BlockFace direction) { super(block, direction); @@ -51,7 +53,7 @@ public class BlockPistonExtendEvent extends BlockPistonEvent { @NotNull public List getBlocks() { if (blocks == null) { - ArrayList tmp = new ArrayList(); + List tmp = new ArrayList(); for (int i = 0; i < this.getLength(); i++) { tmp.add(block.getRelative(getDirection(), i + 1)); } diff --git a/paper-api/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java b/paper-api/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java index 3bfd0f6ed..fec0191ad 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java @@ -7,6 +7,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -24,11 +25,12 @@ public class BlockPlaceEvent extends BlockEvent implements Cancellable { protected Player player; protected EquipmentSlot hand; - @Deprecated(since = "1.9") + @Deprecated(since = "1.9", forRemoval = true) public BlockPlaceEvent(@NotNull final Block placedBlock, @NotNull final BlockState replacedBlockState, @NotNull final Block placedAgainst, @NotNull final ItemStack itemInHand, @NotNull final Player thePlayer, final boolean canBuild) { this(placedBlock, replacedBlockState, placedAgainst, itemInHand, thePlayer, canBuild, EquipmentSlot.HAND); } + @ApiStatus.Internal public BlockPlaceEvent(@NotNull final Block placedBlock, @NotNull final BlockState replacedBlockState, @NotNull final Block placedAgainst, @NotNull final ItemStack itemInHand, @NotNull final Player thePlayer, final boolean canBuild, @NotNull final EquipmentSlot hand) { super(placedBlock); this.placedAgainst = placedAgainst; diff --git a/paper-api/src/main/java/org/bukkit/event/block/SignChangeEvent.java b/paper-api/src/main/java/org/bukkit/event/block/SignChangeEvent.java index e7538a863..a61537af6 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/SignChangeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/SignChangeEvent.java @@ -5,6 +5,7 @@ import org.bukkit.block.sign.Side; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -21,6 +22,7 @@ public class SignChangeEvent extends BlockEvent implements Cancellable { private final Side side; // Paper start + @ApiStatus.Internal public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player player, @NotNull final java.util.List adventure$lines, @NotNull Side side) { super(theBlock); this.player = player; @@ -28,18 +30,18 @@ public class SignChangeEvent extends BlockEvent implements Cancellable { this.side = side; } - @Deprecated + @Deprecated(forRemoval = true) public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player player, @NotNull final java.util.List adventure$lines) { this(theBlock, player, adventure$lines, Side.FRONT); } // Paper end - @Deprecated(since = "1.19.4") + @Deprecated(since = "1.19.4", forRemoval = true) public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player thePlayer, @NotNull final String[] theLines) { this(theBlock, thePlayer, theLines, Side.FRONT); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player thePlayer, @NotNull final String[] theLines, @NotNull Side side) { super(theBlock); this.player = thePlayer; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java index 0c3f8f3f6..6d9c9ca81 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java @@ -57,7 +57,7 @@ public class CreatureSpawnEvent extends EntitySpawnEvent { * {@link ChunkLoadEvent#isNewChunk()} and {@link Chunk#getEntities()} * for similar effect. */ - @Deprecated(since = "1.14") + @Deprecated(since = "1.14", forRemoval = true) CHUNK_GEN, /** * When a creature spawns from a spawner diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java index 3ef5b4254..6cd2d8166 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.entity; import org.bukkit.block.Block; import org.bukkit.entity.Entity; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,11 +12,12 @@ import org.jetbrains.annotations.Nullable; public class EntityCombustByBlockEvent extends EntityCombustEvent { private final Block combuster; - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public EntityCombustByBlockEvent(@Nullable final Block combuster, @NotNull final Entity combustee, final int duration) { this(combuster, combustee, (float) duration); } + @ApiStatus.Internal public EntityCombustByBlockEvent(@Nullable final Block combuster, @NotNull final Entity combustee, final float duration) { super(combustee, duration); this.combuster = combuster; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java index eef8ab889..8cc6e1a90 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java @@ -1,6 +1,7 @@ package org.bukkit.event.entity; import org.bukkit.entity.Entity; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -9,11 +10,12 @@ import org.jetbrains.annotations.NotNull; public class EntityCombustByEntityEvent extends EntityCombustEvent { private final Entity combuster; - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public EntityCombustByEntityEvent(@NotNull final Entity combuster, @NotNull final Entity combustee, final int duration) { this(combuster, combustee, (float) duration); } + @ApiStatus.Internal public EntityCombustByEntityEvent(@NotNull final Entity combuster, @NotNull final Entity combustee, final float duration) { super(combustee, duration); this.combuster = combuster; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java index 1f0f09bcf..239756408 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.entity; 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; /** @@ -15,11 +16,12 @@ public class EntityCombustEvent extends EntityEvent implements Cancellable { private float duration; private boolean cancel; - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public EntityCombustEvent(@NotNull final Entity combustee, final int duration) { this(combustee, (float) duration); } + @ApiStatus.Internal public EntityCombustEvent(@NotNull final Entity combustee, final float duration) { super(combustee); this.duration = duration; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java index 2a36d5b18..2c0103669 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java @@ -20,7 +20,7 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { this(damager, damagee, cause, DamageSource.builder(DamageType.GENERIC).build(), damage); } - @Deprecated + @Deprecated(forRemoval = true) public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, final double damage) { super(damagee, cause, damageSource, damage); this.damager = damager; @@ -32,7 +32,7 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { this(damager, damagee, cause, DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions); } - @Deprecated + @Deprecated(forRemoval = true) public EntityDamageByEntityEvent(@NotNull final Entity damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map modifiers, @NotNull final Map> modifierFunctions) { super(damagee, cause, damageSource, modifiers, modifierFunctions); this.damager = damager; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityPlaceEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityPlaceEvent.java index a7bd15d51..479e2ba0f 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityPlaceEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityPlaceEvent.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,6 +27,7 @@ public class EntityPlaceEvent extends EntityEvent implements Cancellable { private final BlockFace blockFace; private final EquipmentSlot hand; + @ApiStatus.Internal public EntityPlaceEvent(@NotNull final Entity entity, @Nullable final Player player, @NotNull final Block block, @NotNull final BlockFace blockFace, @NotNull final EquipmentSlot hand) { super(entity); this.player = player; @@ -34,7 +36,7 @@ public class EntityPlaceEvent extends EntityEvent implements Cancellable { this.hand = hand; } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public EntityPlaceEvent(@NotNull final Entity entity, @Nullable final Player player, @NotNull final Block block, @NotNull final BlockFace blockFace) { this(entity, player, block, blockFace, EquipmentSlot.HAND); } diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java index 8fdfcbc7d..f6218d317 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityPotionEffectEvent.java @@ -221,7 +221,7 @@ public class EntityPotionEffectEvent extends EntityEvent implements Cancellable * * @deprecated no longer used, player now gets an ominous bottle instead */ - @Deprecated(since = "1.21") // Paper + @Deprecated(since = "1.21", forRemoval = true) PATROL_CAPTAIN, /** * When a potion effect is modified through the plugin methods. diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityResurrectEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityResurrectEvent.java index 372825dc8..2a7426c15 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityResurrectEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityResurrectEvent.java @@ -4,6 +4,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -20,12 +21,13 @@ public class EntityResurrectEvent extends EntityEvent implements Cancellable { private final EquipmentSlot hand; + @ApiStatus.Internal public EntityResurrectEvent(@NotNull LivingEntity what, @Nullable EquipmentSlot hand) { super(what); this.hand = hand; } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public EntityResurrectEvent(@NotNull LivingEntity what) { this(what, null); } diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java index 85e2277ef..d02fa4358 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java @@ -7,6 +7,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.checkerframework.checker.signature.qual.InternalForm; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,16 +39,18 @@ public class EntityShootBowEvent extends EntityEvent implements Cancellable { return this.getConsumable(); } - @Deprecated + @Deprecated(forRemoval = true) public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @NotNull final Entity projectile, final float force) { this(shooter, bow, new ItemStack(org.bukkit.Material.AIR), projectile, force); } - @Deprecated + @Deprecated(forRemoval = true) public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @NotNull ItemStack arrowItem, @NotNull final Entity projectile, final float force) { this(shooter, bow, arrowItem, projectile, EquipmentSlot.HAND, force, true); } // Paper end + + @InternalForm public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @Nullable final ItemStack consumable, @NotNull final Entity projectile, @NotNull final EquipmentSlot hand, final float force, final boolean consumeItem) { super(shooter); this.bow = bow; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java index ef2d1fe4f..e657fe224 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java @@ -105,7 +105,7 @@ public class EntityTargetEvent extends EntityEvent implements Cancellable { * * @deprecated obsoleted by {@link #TARGET_ATTACKED_NEARBY_ENTITY} */ - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) PIG_ZOMBIE_TARGET, /** * When the target is forgotten for whatever reason. diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java index 95248d0f5..98945bce6 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.entity; import org.bukkit.entity.Entity; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -22,11 +23,12 @@ public class EntityUnleashEvent extends EntityEvent implements org.bukkit.event. private boolean cancelled; // Paper // Paper start - drop leash variable - @Deprecated + @Deprecated(forRemoval = true) public EntityUnleashEvent(@NotNull Entity entity, @NotNull UnleashReason reason) { this(entity, reason, false); } + @ApiStatus.Internal public EntityUnleashEvent(@NotNull Entity entity, @NotNull UnleashReason reason, boolean dropLeash) { super(entity); // Paper end diff --git a/paper-api/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java index 7e7132a06..03202de02 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java @@ -5,6 +5,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; import org.bukkit.entity.ThrownExpBottle; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,11 +17,12 @@ public class ExpBottleEvent extends ProjectileHitEvent { private int exp; private boolean showEffect = true; - @Deprecated(since = "1.20.2") + @Deprecated(since = "1.20.2", forRemoval = true) public ExpBottleEvent(@NotNull final ThrownExpBottle bottle, final int exp) { this(bottle, null, null, null, exp); } + @ApiStatus.Internal public ExpBottleEvent(@NotNull final ThrownExpBottle bottle, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, final int exp) { super(bottle, hitEntity, hitBlock, hitFace); this.exp = exp; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java index b38e27605..61a50f95f 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.entity; import org.bukkit.Location; import org.bukkit.entity.Item; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -9,11 +10,12 @@ import org.jetbrains.annotations.NotNull; */ public class ItemSpawnEvent extends EntitySpawnEvent { - @Deprecated(since = "1.13.2") + @Deprecated(since = "1.13.2", forRemoval = true) public ItemSpawnEvent(@NotNull final Item spawnee, final Location loc) { this(spawnee); } + @ApiStatus.Internal public ItemSpawnEvent(@NotNull final Item spawnee) { super(spawnee); } 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 2392885ca..da213dc84 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 @@ -7,6 +7,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,11 +20,12 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca private final AreaEffectCloud entity; private boolean allowEmptyAreaEffectCreation; // Paper - @Deprecated(since = "1.20.2") + @Deprecated(since = "1.20.2", forRemoval = true) public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud entity) { this(potion, null, null, null, entity); } + @ApiStatus.Internal public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final AreaEffectCloud entity) { super(potion, hitEntity, hitBlock, hitFace); this.entity = entity; 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 bba3821d1..ab7584873 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 @@ -34,6 +34,7 @@ public class PlayerDeathEvent extends EntityDeathEvent { // Paper start - shouldDropExperience API this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true); } + @org.jetbrains.annotations.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 net.kyori.adventure.text.Component deathMessage, final boolean doExpDrop) { // Paper end - shouldDropExperience API @@ -46,23 +47,23 @@ public class PlayerDeathEvent extends EntityDeathEvent { } // Paper end - adventure - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List drops, final int droppedExp, @Nullable final String deathMessage) { this(player, damageSource, drops, droppedExp, 0, deathMessage); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List drops, final int droppedExp, final int newExp, @Nullable final String deathMessage) { this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerDeathEvent(@NotNull final Player player, @NotNull DamageSource damageSource, @NotNull final List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage) { // Paper start - shouldDropExperience API this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerDeathEvent(@NotNull final Player player, final @NotNull DamageSource damageSource, @NotNull final List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage, boolean doExpDrop) { // Paper end - shouldDropExperience API super(player, damageSource, drops, droppedExp); diff --git a/paper-api/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java index d7205c2b5..e58e0b1d6 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java @@ -6,6 +6,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -19,6 +20,7 @@ public class PlayerLeashEntityEvent extends Event implements Cancellable { private final Player player; private final EquipmentSlot hand; + @ApiStatus.Internal public PlayerLeashEntityEvent(@NotNull Entity what, @NotNull Entity leashHolder, @NotNull Player leasher, @NotNull EquipmentSlot hand) { this.leashHolder = leashHolder; this.entity = what; @@ -26,7 +28,7 @@ public class PlayerLeashEntityEvent extends Event implements Cancellable { this.hand = hand; } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerLeashEntityEvent(@NotNull Entity what, @NotNull Entity leashHolder, @NotNull Player leasher) { this(what, leashHolder, leasher, EquipmentSlot.HAND); } diff --git a/paper-api/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java index f079cd30b..82ee49da5 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java @@ -11,6 +11,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.ThrownPotion; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,11 +23,12 @@ public class PotionSplashEvent extends ProjectileHitEvent implements Cancellable private boolean cancelled; protected final Map affectedEntities; // Paper - @Deprecated(since = "1.20.2") + @Deprecated(since = "1.20.2", forRemoval = true) public PotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final Map affectedEntities) { this(potion, null, null, null, affectedEntities); } + @ApiStatus.Internal public PotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final Map affectedEntities) { super(potion, hitEntity, hitBlock, hitFace); this.affectedEntities = affectedEntities; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java index 7fccda2a4..b64b41e6b 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java @@ -6,6 +6,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Projectile; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,27 +20,27 @@ public class ProjectileHitEvent extends EntityEvent implements Cancellable { private final BlockFace hitFace; private boolean cancel = false; - @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper + @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Paper public ProjectileHitEvent(@NotNull final Projectile projectile) { this(projectile, null, null, null); // Paper } - @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper + @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Paper public ProjectileHitEvent(@NotNull final Projectile projectile, @Nullable Entity hitEntity) { this(projectile, hitEntity, null, null); // Paper } - @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper + @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Paper public ProjectileHitEvent(@NotNull final Projectile projectile, @Nullable Block hitBlock) { this(projectile, null, hitBlock, null); // Paper } - @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper + @Deprecated(forRemoval = true) @io.papermc.paper.annotation.DoNotUse // Paper public ProjectileHitEvent(@NotNull final Projectile projectile, @Nullable Entity hitEntity, @Nullable Block hitBlock) { this(projectile, hitEntity, hitBlock, null); } - @org.jetbrains.annotations.ApiStatus.Internal // Paper + @ApiStatus.Internal public ProjectileHitEvent(@NotNull final Projectile projectile, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace) { super(projectile); this.hitEntity = hitEntity; diff --git a/paper-api/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java index 5d056d6bc..f3afd40c8 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import org.bukkit.entity.Sheep; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -14,11 +15,12 @@ import org.jetbrains.annotations.Nullable; public class SheepDyeWoolEvent extends io.papermc.paper.event.entity.EntityDyeEvent implements Cancellable { // Paper - move everything to superclass - @Deprecated(since = "1.17.1") + @Deprecated(since = "1.17.1", forRemoval = true) public SheepDyeWoolEvent(@NotNull final Sheep sheep, @NotNull final DyeColor color) { this(sheep, color, null); } + @ApiStatus.Internal public SheepDyeWoolEvent(@NotNull final Sheep sheep, @NotNull final DyeColor color, @Nullable Player player) { super(sheep, color, player); // Paper } diff --git a/paper-api/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java b/paper-api/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java index 6bcc20cea..08ff883d9 100644 --- a/paper-api/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java @@ -8,6 +8,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,6 +29,7 @@ public class HangingPlaceEvent extends HangingEvent implements Cancellable { this(hanging, player, block, blockFace, hand, null); } + @ApiStatus.Internal public HangingPlaceEvent(@NotNull final Hanging hanging, @Nullable final Player player, @NotNull final Block block, @NotNull final BlockFace blockFace, @Nullable final EquipmentSlot hand, @Nullable ItemStack itemStack) { super(hanging); this.player = player; diff --git a/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java b/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java index 25478725b..714d9d75a 100644 --- a/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.inventory; import org.bukkit.block.Block; import org.bukkit.event.block.BlockCookEvent; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -12,13 +13,13 @@ import org.jetbrains.annotations.NotNull; */ public class FurnaceSmeltEvent extends BlockCookEvent { - @Deprecated // Paper + @Deprecated(forRemoval = true) public FurnaceSmeltEvent(@NotNull final Block furnace, @NotNull final ItemStack source, @NotNull final ItemStack result) { super(furnace, source, result); } - // Paper start + + @ApiStatus.Internal public FurnaceSmeltEvent(@NotNull final Block furnace, @NotNull final ItemStack source, @NotNull final ItemStack result, @org.jetbrains.annotations.Nullable org.bukkit.inventory.CookingRecipe recipe) { super(furnace, source, result, recipe); } - // Paper end } diff --git a/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceStartSmeltEvent.java b/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceStartSmeltEvent.java index abfd0441f..6226beaa3 100644 --- a/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceStartSmeltEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/inventory/FurnaceStartSmeltEvent.java @@ -5,6 +5,7 @@ import org.bukkit.event.HandlerList; import org.bukkit.event.block.InventoryBlockStartEvent; import org.bukkit.inventory.CookingRecipe; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -18,12 +19,13 @@ public class FurnaceStartSmeltEvent extends InventoryBlockStartEvent { private final CookingRecipe recipe; private int totalCookTime; - @Deprecated // Paper - furnace cook speed multiplier + @Deprecated(forRemoval = true) public FurnaceStartSmeltEvent(@NotNull final Block furnace, @NotNull ItemStack source, @NotNull final CookingRecipe recipe) { // Paper start this(furnace, source, recipe, recipe.getCookingTime()); } + @ApiStatus.Internal public FurnaceStartSmeltEvent(final @NotNull Block furnace, final @NotNull ItemStack source, final @NotNull CookingRecipe recipe, final int cookingTime) { // Paper end super(furnace, source); diff --git a/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java b/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java index b84aaf7f3..254886cfe 100644 --- a/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java +++ b/paper-api/src/main/java/org/bukkit/event/inventory/InventoryAction.java @@ -72,7 +72,7 @@ public enum InventoryAction { * The hotbar includes the player's off hand. * @deprecated This action no longer happens, they are all {@link #HOTBAR_SWAP}s. */ - @Deprecated(since = "1.20.6") // Paper + @Deprecated(since = "1.20.6", forRemoval = true) // Paper HOTBAR_MOVE_AND_READD, /** * The clicked slot and the picked hotbar slot are swapped. diff --git a/paper-api/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/paper-api/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java index ff5cca4a7..c8479838e 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java @@ -4,6 +4,7 @@ import java.net.InetAddress; import java.util.UUID; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -28,16 +29,17 @@ public class AsyncPlayerPreLoginEvent extends Event { private final String hostname; // Paper private final boolean transferred; - @Deprecated(since = "1.7.5") + @Deprecated(since = "1.7.5", forRemoval = true) public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress) { this(name, ipAddress, null); } - @Deprecated(since = "1.20.5") + @Deprecated(since = "1.20.5", forRemoval = true) public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId) { this(name, ipAddress, uniqueId, false); } + @ApiStatus.Internal public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId, boolean transferred) { // Paper start this(name, ipAddress, uniqueId, transferred, org.bukkit.Bukkit.createProfile(uniqueId, name)); @@ -53,7 +55,7 @@ public class AsyncPlayerPreLoginEvent extends Event { this(name, ipAddress, rawAddress, uniqueId, transferred, profile, ""); } - @org.jetbrains.annotations.ApiStatus.Internal + @ApiStatus.Internal public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final InetAddress rawAddress, @NotNull final UUID uniqueId, boolean transferred, @NotNull com.destroystokyo.paper.profile.PlayerProfile profile, @NotNull String hostname) { // Paper end super(true); diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java index 0c7e3a0c4..9eb6141a1 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.player; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -14,7 +15,7 @@ public class PlayerAnimationEvent extends PlayerEvent implements Cancellable { private final PlayerAnimationType animationType; private boolean isCancelled = false; - @Deprecated(since = "1.19") + @Deprecated(since = "1.19", forRemoval = true) public PlayerAnimationEvent(@NotNull final Player player) { this(player, PlayerAnimationType.ARM_SWING); } @@ -25,6 +26,7 @@ public class PlayerAnimationEvent extends PlayerEvent implements Cancellable { * @param player The player instance * @param playerAnimationType The animation type */ + @ApiStatus.Internal public PlayerAnimationEvent(@NotNull final Player player, @NotNull final PlayerAnimationType playerAnimationType) { super(player); animationType = playerAnimationType; diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java index 75154912b..04dbcb41b 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java @@ -26,7 +26,7 @@ public class PlayerArmorStandManipulateEvent extends PlayerInteractEntityEvent { this.slot = slot; } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerArmorStandManipulateEvent(@NotNull final Player who, @NotNull final ArmorStand clickedEntity, @NotNull final ItemStack playerItem, @NotNull final ItemStack armorStandItem, @NotNull final EquipmentSlot slot) { this(who, clickedEntity, playerItem, armorStandItem, slot, EquipmentSlot.HAND); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java index eff29875f..812712494 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java @@ -21,7 +21,7 @@ public class PlayerAttemptPickupItemEvent extends PlayerEvent implements Cancell private boolean cancelled; - @Deprecated // Remove in 1.13 // Remove in 1.14? + @Deprecated(forRemoval = true) // Remove in 1.13 // Remove in 1.14? // Remove before the heat death of the universe? @ApiStatus.Internal public PlayerAttemptPickupItemEvent(final Player player, final Item item) { this(player, item, 0); diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java index dad760bbb..96c9b7fe0 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java @@ -5,6 +5,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -63,13 +64,14 @@ public class PlayerBedEnterEvent extends PlayerEvent implements Cancellable { private final BedEnterResult bedEnterResult; private Result useBed = Result.DEFAULT; + @ApiStatus.Internal public PlayerBedEnterEvent(@NotNull Player who, @NotNull Block bed, @NotNull BedEnterResult bedEnterResult) { super(who); this.bed = bed; this.bedEnterResult = bedEnterResult; } - @Deprecated(since = "1.13.2") + @Deprecated(since = "1.13.2", forRemoval = true) public PlayerBedEnterEvent(@NotNull Player who, @NotNull Block bed) { this(who, bed, BedEnterResult.OK); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java index bea5b52f6..36e02c71d 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -15,16 +16,17 @@ import org.jetbrains.annotations.NotNull; public class PlayerBucketEmptyEvent extends PlayerBucketEvent { private static final HandlerList handlers = new HandlerList(); - @Deprecated(since = "1.14.4") + @Deprecated(since = "1.14.4", forRemoval = true) public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) { super(who, blockClicked, blockFace, bucket, itemInHand); } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) { super(who, block, blockClicked, blockFace, bucket, itemInHand); } + @ApiStatus.Internal public PlayerBucketEmptyEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @NotNull final EquipmentSlot hand) { super(who, block, blockClicked, blockFace, bucket, itemInHand, hand); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java index 71f18c2b4..0e07667be 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java @@ -9,6 +9,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,16 +25,17 @@ public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellab private final Material bucket; private final EquipmentSlot hand; - @Deprecated(since = "1.14.4") + @Deprecated(since = "1.14.4", forRemoval = true) public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) { this(who, null, blockClicked.getRelative(blockFace), blockFace, bucket, itemInHand, EquipmentSlot.HAND); } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) { this(who, block, blockClicked, blockFace, bucket, itemInHand, EquipmentSlot.HAND); } + @ApiStatus.Internal public PlayerBucketEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @NotNull final EquipmentSlot hand) { super(who); this.block = block; diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java index 3789b1a56..c74c33e7d 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -15,16 +16,17 @@ import org.jetbrains.annotations.NotNull; public class PlayerBucketFillEvent extends PlayerBucketEvent { private static final HandlerList handlers = new HandlerList(); - @Deprecated(since = "1.14.4") + @Deprecated(since = "1.14.4", forRemoval = true) public PlayerBucketFillEvent(@NotNull final Player who, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) { super(who, blockClicked, blockFace, bucket, itemInHand); } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerBucketFillEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand) { super(who, block, blockClicked, blockFace, bucket, itemInHand); } + @ApiStatus.Internal public PlayerBucketFillEvent(@NotNull final Player who, @NotNull final Block block, @NotNull final Block blockClicked, @NotNull final BlockFace blockFace, @NotNull final Material bucket, @NotNull final ItemStack itemInHand, @NotNull final EquipmentSlot hand) { super(who, block, blockClicked, blockFace, bucket, itemInHand, hand); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java index d716a9df0..77dff6319 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java @@ -74,7 +74,7 @@ public class PlayerEditBookEvent extends PlayerEvent implements Cancellable { * @return the inventory slot number that the book item occupies * @deprecated books may be signed from off hand */ - @Deprecated(since = "1.13.1") + @Deprecated(since = "1.13.1", forRemoval = true) public int getSlot() { return slot; } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java index aee4a8b52..996f58fb7 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java @@ -4,6 +4,7 @@ import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -22,12 +23,13 @@ public class PlayerGameModeChangeEvent extends PlayerEvent implements Cancellabl private final Cause cause; private net.kyori.adventure.text.Component cancelMessage; - @Deprecated // Paper end + @Deprecated(forRemoval = true) // Paper end public PlayerGameModeChangeEvent(@NotNull final Player player, @NotNull final GameMode newGameMode) { // Paper start this(player, newGameMode, Cause.UNKNOWN, null); } + @ApiStatus.Internal public PlayerGameModeChangeEvent(@NotNull final Player player, @NotNull final GameMode newGameMode, @NotNull Cause cause, @org.jetbrains.annotations.Nullable net.kyori.adventure.text.Component cancelMessage) { // Paper end super(player); diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerHarvestBlockEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerHarvestBlockEvent.java index 805aa2010..f18ee5a8d 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerHarvestBlockEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerHarvestBlockEvent.java @@ -7,6 +7,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -27,6 +28,7 @@ public class PlayerHarvestBlockEvent extends PlayerEvent implements Cancellable private final EquipmentSlot hand; private final List itemsHarvested; + @ApiStatus.Internal public PlayerHarvestBlockEvent(@NotNull Player player, @NotNull Block harvestedBlock, @NotNull EquipmentSlot hand, @NotNull List itemsHarvested) { super(player); this.harvestedBlock = harvestedBlock; @@ -34,7 +36,7 @@ public class PlayerHarvestBlockEvent extends PlayerEvent implements Cancellable this.itemsHarvested = itemsHarvested; } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerHarvestBlockEvent(@NotNull Player player, @NotNull Block harvestedBlock, @NotNull List itemsHarvested) { this(player, harvestedBlock, EquipmentSlot.HAND, itemsHarvested); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java index 3208dedfb..4cd915b0c 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java @@ -6,6 +6,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,6 +32,7 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable { * @param item the ItemStack being consumed * @param hand the hand that was used */ + @ApiStatus.Internal public PlayerItemConsumeEvent(@NotNull final Player player, @NotNull final ItemStack item, @NotNull final EquipmentSlot hand) { super(player); @@ -43,7 +45,7 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable { * @param item the ItemStack being consumed * @deprecated use {@link #PlayerItemConsumeEvent(Player, ItemStack, EquipmentSlot)} */ - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerItemConsumeEvent(@NotNull final Player player, @NotNull final ItemStack item) { this(player, item, EquipmentSlot.HAND); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java index a2993c743..c55f1b971 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java @@ -4,6 +4,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -14,16 +15,17 @@ public class PlayerItemDamageEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private final ItemStack item; + private final int originalDamage; private int damage; - private int originalDamage; // Paper - Add pre-reduction damage private boolean cancelled = false; - @Deprecated // Paper - Add pre-reduction damage + @Deprecated(forRemoval = true) public PlayerItemDamageEvent(@NotNull Player player, @NotNull ItemStack what, int damage) { // Paper start - Add pre-reduction damage this(player, what, damage, damage); } + @ApiStatus.Internal public PlayerItemDamageEvent(@NotNull Player player, @NotNull ItemStack what, int damage, int originalDamage) { super(player); this.item = what; diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemMendEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemMendEvent.java index f0533271d..7471cb755 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerItemMendEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerItemMendEvent.java @@ -6,6 +6,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -26,13 +27,13 @@ public class PlayerItemMendEvent extends PlayerEvent implements Cancellable { private boolean cancelled; private final int consumedExperience; // Paper - @Deprecated // Paper + @Deprecated(forRemoval = true) // Paper public PlayerItemMendEvent(@NotNull Player who, @NotNull ItemStack item, @NotNull EquipmentSlot slot, @NotNull ExperienceOrb experienceOrb, int repairAmount) { // Paper start this(who, item, slot, experienceOrb, repairAmount, repairAmount / 2); } - @org.jetbrains.annotations.ApiStatus.Internal + @ApiStatus.Internal public PlayerItemMendEvent(@NotNull Player who, @NotNull ItemStack item, @NotNull EquipmentSlot slot, @NotNull ExperienceOrb experienceOrb, int repairAmount, int consumedExperience) { // Paper end super(who); @@ -86,7 +87,7 @@ public class PlayerItemMendEvent extends PlayerEvent implements Cancellable { } // Paper end - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerItemMendEvent(@NotNull Player who, @NotNull ItemStack item, @NotNull ExperienceOrb experienceOrb, int repairAmount) { this(who, item, null, experienceOrb, repairAmount); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java index 3e1e7cd04..027e3d2c4 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.player; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,12 +13,14 @@ public class PlayerJoinEvent extends PlayerEvent { private static final HandlerList handlers = new HandlerList(); // Paper start private net.kyori.adventure.text.Component joinMessage; + + @ApiStatus.Internal public PlayerJoinEvent(@NotNull final Player playerJoined, @Nullable final net.kyori.adventure.text.Component joinMessage) { super(playerJoined); this.joinMessage = joinMessage; } - @Deprecated // Paper end + @Deprecated(forRemoval = true) // Paper end public PlayerJoinEvent(@NotNull final Player playerJoined, @Nullable final String joinMessage) { super(playerJoined); this.joinMessage = joinMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(joinMessage) : null; // Paper end diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerKickEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerKickEvent.java index b8bf61bea..09ea15c3d 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerKickEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerKickEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.player; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -15,7 +16,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable { private final Cause cause; // Paper private boolean cancel; - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerKickEvent(@NotNull final Player playerKicked, @NotNull final String kickReason, @NotNull final String leaveMessage) { super(playerKicked); this.kickReason = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(kickReason); // Paper @@ -24,7 +25,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable { this.cancel = false; } // Paper start - @Deprecated + @Deprecated(forRemoval = true) public PlayerKickEvent(@NotNull final Player playerKicked, @NotNull final net.kyori.adventure.text.Component kickReason, @NotNull final net.kyori.adventure.text.Component leaveMessage) { super(playerKicked); this.kickReason = kickReason; @@ -33,7 +34,7 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable { this.cause = Cause.UNKNOWN; } - @org.jetbrains.annotations.ApiStatus.Internal + @ApiStatus.Internal public PlayerKickEvent(@NotNull final Player playerKicked, @NotNull final net.kyori.adventure.text.Component kickReason, @NotNull final net.kyori.adventure.text.Component leaveMessage, @NotNull final Cause cause) { super(playerKicked); this.kickReason = kickReason; diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java index eaa0548cf..8d67cd1f7 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.player; import java.net.InetAddress; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -30,6 +31,7 @@ public class PlayerLoginEvent extends PlayerEvent { * timing issues * @param realAddress the actual, unspoofed connecting address */ + @ApiStatus.Internal public PlayerLoginEvent(@NotNull final Player player, @NotNull final String hostname, @NotNull final InetAddress address, final @NotNull InetAddress realAddress) { super(player); this.hostname = hostname; @@ -46,6 +48,7 @@ public class PlayerLoginEvent extends PlayerEvent { * @param address The address the player used to connect, provided for * timing issues */ + @ApiStatus.Internal public PlayerLoginEvent(@NotNull final Player player, @NotNull final String hostname, @NotNull final InetAddress address) { this(player, hostname, address, address); } @@ -62,7 +65,7 @@ public class PlayerLoginEvent extends PlayerEvent { * @param realAddress the actual, unspoofed connecting address * @deprecated in favour of {@link #PlayerLoginEvent(Player, String, InetAddress, Result, net.kyori.adventure.text.Component, InetAddress)} */ - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerLoginEvent(@NotNull final Player player, @NotNull String hostname, @NotNull final InetAddress address, @NotNull final Result result, @NotNull final String message, @NotNull final InetAddress realAddress) { this(player, hostname, address, realAddress); this.result = result; @@ -81,6 +84,7 @@ public class PlayerLoginEvent extends PlayerEvent { * @param message The message to be displayed if result denies login * @param realAddress the actual, unspoofed connecting address */ + @ApiStatus.Internal public PlayerLoginEvent(@NotNull final Player player, @NotNull String hostname, @NotNull final InetAddress address, @NotNull final Result result, @NotNull final net.kyori.adventure.text.Component message, @NotNull final InetAddress realAddress) { this(player, hostname, address, realAddress); // Spigot this.result = result; diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java index 929a99767..a6fa22e4f 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java @@ -62,7 +62,7 @@ public class PlayerPortalEvent extends PlayerTeleportEvent { * @return no effect * @deprecated No effect */ - @Deprecated + @Deprecated(forRemoval = true) @Override public boolean willDismountPlayer() { return super.willDismountPlayer(); @@ -73,7 +73,7 @@ public class PlayerPortalEvent extends PlayerTeleportEvent { * @return no effect * @deprecated No effect */ - @Deprecated + @Deprecated(forRemoval = true) @Override public @NotNull java.util.Set getRelativeTeleportationFlags() { return super.getRelativeTeleportationFlags(); diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java index b323212f1..b2b1c04b0 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java @@ -5,6 +5,7 @@ import java.util.UUID; import org.bukkit.Warning; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -31,11 +32,12 @@ public class PlayerPreLoginEvent extends Event { private final InetAddress ipAddress; private final UUID uniqueId; - @Deprecated(since = "1.7.5") + @Deprecated(since = "1.7.5", forRemoval = true) public PlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress) { this(name, ipAddress, null); } + @ApiStatus.Internal public PlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId) { this.result = Result.ALLOWED; this.message = net.kyori.adventure.text.Component.empty(); // Paper diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java index 84703b5d1..891d72500 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java @@ -2,6 +2,7 @@ package org.bukkit.event.player; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,22 +14,24 @@ public class PlayerQuitEvent extends PlayerEvent { private net.kyori.adventure.text.Component quitMessage; // Paper private final QuitReason reason; // Paper - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage) { // Paper start this(who, quitMessage, null); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage, @Nullable QuitReason quitReason) { super(who); this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper this.reason = quitReason == null ? QuitReason.DISCONNECTED : quitReason; } // Paper start - @Deprecated + @Deprecated(forRemoval = true) public PlayerQuitEvent(@NotNull final Player who, @Nullable final net.kyori.adventure.text.Component quitMessage) { this(who, quitMessage, null); } + + @ApiStatus.Internal public PlayerQuitEvent(@NotNull final Player who, @Nullable final net.kyori.adventure.text.Component quitMessage, @Nullable QuitReason quitReason) { super(who); this.quitMessage = quitMessage; 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 d1dd5cf0a..450a3cc54 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 @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -20,22 +21,23 @@ public class PlayerRespawnEvent extends PlayerEvent { private final RespawnReason respawnReason; private final java.util.Set respawnFlags; // Paper - @Deprecated(since = "1.16.1") + @Deprecated(since = "1.16.1", forRemoval = true) public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn) { this(respawnPlayer, respawnLocation, isBedSpawn, false); } - @Deprecated(since = "1.19.4") + @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, false, RespawnReason.PLUGIN); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, @NotNull final RespawnReason respawnReason) { // Paper start this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, 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, @NotNull final RespawnReason respawnReason, @NotNull final com.google.common.collect.ImmutableSet.Builder respawnFlags) { // Paper end super(respawnPlayer); diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerRiptideEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerRiptideEvent.java index a3f63b908..e0fd25b59 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerRiptideEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerRiptideEvent.java @@ -4,6 +4,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -19,13 +20,14 @@ public class PlayerRiptideEvent extends PlayerEvent { private final ItemStack item; private final Vector velocity; + @ApiStatus.Internal public PlayerRiptideEvent(@NotNull final Player who, @NotNull final ItemStack item, @NotNull Vector velocity) { super(who); this.item = item; this.velocity = velocity; } - @Deprecated(since = "1.20.4") + @Deprecated(since = "1.20.4", forRemoval = true) public PlayerRiptideEvent(@NotNull final Player who, @NotNull final ItemStack item) { this(who, item, new Vector()); } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java index 3a12674e4..a252c74f3 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java @@ -7,6 +7,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -20,7 +21,7 @@ public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { private final EquipmentSlot hand; private java.util.List drops; // Paper - custom shear drops - @org.jetbrains.annotations.ApiStatus.Internal // Paper + @ApiStatus.Internal public PlayerShearEntityEvent(@NotNull Player who, @NotNull Entity what, @NotNull ItemStack item, @NotNull EquipmentSlot hand, final java.util.@NotNull List drops) { // Paper - custom shear drops super(who); this.what = what; @@ -29,7 +30,7 @@ public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { this.drops = drops; // Paper - custom shear drops } - @Deprecated(since = "1.15.2") + @Deprecated(since = "1.15.2", forRemoval = true) public PlayerShearEntityEvent(@NotNull final Player who, @NotNull final Entity what) { this(who, what, new ItemStack(Material.SHEARS), EquipmentSlot.HAND, java.util.Collections.emptyList()); // Paper - custom shear drops } diff --git a/paper-api/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java b/paper-api/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java index ade7b2689..0b02a75f0 100644 --- a/paper-api/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.entity.EntityUnleashEvent; import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -18,11 +19,12 @@ public class PlayerUnleashEntityEvent extends EntityUnleashEvent implements Canc private final EquipmentSlot hand; // Paper start - drop leash variable - @Deprecated + @Deprecated(forRemoval = true) public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player, @NotNull EquipmentSlot hand) { this(entity, player, hand, false); } + @ApiStatus.Internal public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player, @NotNull EquipmentSlot hand, boolean dropLeash) { super(entity, UnleashReason.PLAYER_UNLEASH, dropLeash); // Paper end @@ -30,7 +32,7 @@ public class PlayerUnleashEntityEvent extends EntityUnleashEvent implements Canc this.hand = hand; } - @Deprecated(since = "1.19.2") + @Deprecated(since = "1.19.2", forRemoval = true) public PlayerUnleashEntityEvent(@NotNull Entity entity, @NotNull Player player) { this(entity, player, EquipmentSlot.HAND); } diff --git a/paper-api/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java b/paper-api/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java index 173cdb379..eb27cbe13 100644 --- a/paper-api/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java @@ -5,6 +5,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -22,12 +23,12 @@ public class BroadcastMessageEvent extends ServerEvent implements Cancellable { private final Set recipients; private boolean cancelled = false; - @Deprecated(since = "1.14") + @Deprecated(since = "1.14", forRemoval = true) public BroadcastMessageEvent(@NotNull String message, @NotNull Set recipients) { this(false, message, recipients); } - @Deprecated // Paper + @Deprecated(forRemoval = true) public BroadcastMessageEvent(boolean isAsync, @NotNull String message, @NotNull Set recipients) { // Paper start super(isAsync); @@ -35,11 +36,12 @@ public class BroadcastMessageEvent extends ServerEvent implements Cancellable { this.recipients = recipients; } - @Deprecated + @Deprecated(forRemoval = true) public BroadcastMessageEvent(net.kyori.adventure.text.@NotNull Component message, @NotNull Set recipients) { this(false, message, recipients); } + @ApiStatus.Internal public BroadcastMessageEvent(boolean isAsync, net.kyori.adventure.text.@NotNull Component message, @NotNull Set recipients) { // Paper end super(isAsync); diff --git a/paper-api/src/main/java/org/bukkit/event/server/ServerListPingEvent.java b/paper-api/src/main/java/org/bukkit/event/server/ServerListPingEvent.java index e11b81e71..8a04bdd74 100644 --- a/paper-api/src/main/java/org/bukkit/event/server/ServerListPingEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/server/ServerListPingEvent.java @@ -8,6 +8,7 @@ import org.bukkit.UndefinedNullability; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.util.CachedServerIcon; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -26,6 +27,8 @@ public class ServerListPingEvent extends ServerEvent implements Iterable private final int numPlayers; private int maxPlayers; + @Deprecated(forRemoval = true) + @ApiStatus.Internal public ServerListPingEvent(@NotNull final String hostname, @NotNull final InetAddress address, @NotNull final String motd, final int numPlayers, final int maxPlayers) { super(true); Preconditions.checkArgument(numPlayers >= 0, "Cannot have negative number of players online", numPlayers); @@ -47,7 +50,8 @@ public class ServerListPingEvent extends ServerEvent implements Iterable * @param maxPlayers the max number of players * @deprecated in favour of {@link #ServerListPingEvent(String, java.net.InetAddress, net.kyori.adventure.text.Component, int)} */ - @Deprecated // Paper + @Deprecated(forRemoval = true) + @ApiStatus.Internal protected ServerListPingEvent(@NotNull final String hostname, @NotNull final InetAddress address, @NotNull final String motd, final int maxPlayers) { super(true); this.numPlayers = MAGIC_PLAYER_COUNT; @@ -56,11 +60,14 @@ public class ServerListPingEvent extends ServerEvent implements Iterable this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper this.maxPlayers = maxPlayers; } - // Paper start - @Deprecated + + @Deprecated(forRemoval = true) + @ApiStatus.Internal public ServerListPingEvent(@NotNull final InetAddress address, @NotNull final net.kyori.adventure.text.Component motd, final int numPlayers, final int maxPlayers) { this("", address, motd, numPlayers, maxPlayers); } + + @ApiStatus.Internal public ServerListPingEvent(@NotNull final String hostname, @NotNull final InetAddress address, @NotNull final net.kyori.adventure.text.Component motd, final int numPlayers, final int maxPlayers) { super(true); Preconditions.checkArgument(numPlayers >= 0, "Cannot have negative number of players online (%s)", numPlayers); @@ -80,7 +87,8 @@ public class ServerListPingEvent extends ServerEvent implements Iterable * @param maxPlayers the max number of players * @deprecated in favour of {@link #ServerListPingEvent(String, java.net.InetAddress, net.kyori.adventure.text.Component, int)} */ - @Deprecated + @Deprecated(forRemoval = true) + @ApiStatus.Internal protected ServerListPingEvent(@NotNull final InetAddress address, @NotNull final net.kyori.adventure.text.Component motd, final int maxPlayers) { this("", address, motd, maxPlayers); } @@ -95,6 +103,7 @@ public class ServerListPingEvent extends ServerEvent implements Iterable * @param motd the message of the day * @param maxPlayers the max number of players */ + @ApiStatus.Internal protected ServerListPingEvent(final @NotNull String hostname, final @NotNull InetAddress address, final net.kyori.adventure.text.@NotNull Component motd, final int maxPlayers) { this.numPlayers = MAGIC_PLAYER_COUNT; this.hostname = hostname; @@ -118,7 +127,6 @@ public class ServerListPingEvent extends ServerEvent implements Iterable public void motd(net.kyori.adventure.text.@NotNull Component motd) { this.motd = motd; } - // Paper end /** * Gets the hostname that the player used to connect to the server, or @@ -196,7 +204,7 @@ public class ServerListPingEvent extends ServerEvent implements Iterable * @return true if chat preview is enabled, false otherwise * @deprecated chat previews have been removed */ - @Deprecated(since = "1.19.3") + @Deprecated(since = "1.19.3", forRemoval = true) public boolean shouldSendChatPreviews() { return false; } diff --git a/paper-api/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java b/paper-api/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java index 50fad23cf..d7cfd5f8a 100644 --- a/paper-api/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.vehicle; import org.bukkit.block.Block; import org.bukkit.entity.Vehicle; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -13,11 +14,12 @@ public class VehicleBlockCollisionEvent extends VehicleCollisionEvent { private final org.bukkit.util.Vector velocity; // Paper // Paper start - Add pre-collision velocity - @Deprecated + @Deprecated(forRemoval = true) public VehicleBlockCollisionEvent(@NotNull final Vehicle vehicle, @NotNull final Block block) { this(vehicle, block, vehicle.getVelocity()); } + @ApiStatus.Internal public VehicleBlockCollisionEvent(@NotNull final Vehicle vehicle, @NotNull final Block block, @NotNull final org.bukkit.util.Vector velocity) { // Paper - Added velocity super(vehicle); this.block = block; diff --git a/paper-api/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java b/paper-api/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java index ca97efaaa..50696f04f 100644 --- a/paper-api/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java @@ -4,6 +4,7 @@ import org.bukkit.World; import org.bukkit.entity.LightningStrike; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -15,11 +16,12 @@ public class LightningStrikeEvent extends WeatherEvent implements Cancellable { private final LightningStrike bolt; private final Cause cause; - @Deprecated(since = "1.13.1") + @Deprecated(since = "1.13.1", forRemoval = true) public LightningStrikeEvent(@NotNull final World world, @NotNull final LightningStrike bolt) { this(world, bolt, Cause.UNKNOWN); } + @ApiStatus.Internal public LightningStrikeEvent(@NotNull final World world, @NotNull final LightningStrike bolt, @NotNull final Cause cause) { super(world); this.bolt = bolt; diff --git a/paper-api/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java b/paper-api/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java index 032395c71..f787596d2 100644 --- a/paper-api/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.weather; import org.bukkit.World; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -12,16 +13,16 @@ public class ThunderChangeEvent extends WeatherEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean canceled; private final boolean to; - // Paper start private final Cause cause; + @ApiStatus.Internal public ThunderChangeEvent(@NotNull final World world, final boolean to, @NotNull final Cause cause) { super(world); this.to = to; this.cause = cause; } - @Deprecated // Paper end + @Deprecated(forRemoval = true) public ThunderChangeEvent(@NotNull final World world, final boolean to) { super(world); this.to = to; diff --git a/paper-api/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java b/paper-api/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java index dabd390b8..c8aa324b7 100644 --- a/paper-api/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java @@ -3,6 +3,7 @@ package org.bukkit.event.weather; import org.bukkit.World; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -12,16 +13,16 @@ public class WeatherChangeEvent extends WeatherEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private boolean canceled; private final boolean to; - // Paper start private final Cause cause; + @ApiStatus.Internal public WeatherChangeEvent(@NotNull final World world, final boolean to, @NotNull Cause cause) { super(world); this.to = to; this.cause = cause; } - @Deprecated // Paper end + @Deprecated(forRemoval = true) public WeatherChangeEvent(@NotNull final World world, final boolean to) { super(world); this.to = to; diff --git a/paper-api/src/main/java/org/bukkit/event/world/PortalCreateEvent.java b/paper-api/src/main/java/org/bukkit/event/world/PortalCreateEvent.java index a7acc3ab3..b7789781f 100644 --- a/paper-api/src/main/java/org/bukkit/event/world/PortalCreateEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/world/PortalCreateEvent.java @@ -6,6 +6,7 @@ import org.bukkit.block.BlockState; 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.jetbrains.annotations.Nullable; @@ -19,11 +20,12 @@ public class PortalCreateEvent extends WorldEvent implements Cancellable { private final Entity entity; private final CreateReason reason; - @Deprecated(since = "1.14.1") + @Deprecated(since = "1.14.1", forRemoval = true) public PortalCreateEvent(@NotNull final List blocks, @NotNull final World world, @NotNull CreateReason reason) { this(blocks, world, null, reason); } + @ApiStatus.Internal public PortalCreateEvent(@NotNull final List blocks, @NotNull final World world, @Nullable Entity entity, @NotNull CreateReason reason) { super(world); diff --git a/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java b/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java index d76fbab34..c922da90e 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java +++ b/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java @@ -4,6 +4,7 @@ import java.util.Collections; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.material.MaterialData; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -11,22 +12,22 @@ import org.jetbrains.annotations.NotNull; */ public class FurnaceRecipe extends CookingRecipe { - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) public FurnaceRecipe(@NotNull ItemStack result, @NotNull Material source) { this(NamespacedKey.randomKey(), result, source, 0, 0, 200); } - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) public FurnaceRecipe(@NotNull ItemStack result, @NotNull MaterialData source) { this(NamespacedKey.randomKey(), result, source.getItemType(), source.getData(), 0, 200); } - @Deprecated(since = "1.13") + @Deprecated(since = "1.13", forRemoval = true) public FurnaceRecipe(@NotNull ItemStack result, @NotNull MaterialData source, float experience) { this(NamespacedKey.randomKey(), result, source.getItemType(), source.getData(), experience, 200); } - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) public FurnaceRecipe(@NotNull ItemStack result, @NotNull Material source, int data) { this(NamespacedKey.randomKey(), result, source, data, 0, 200); } @@ -40,11 +41,12 @@ public class FurnaceRecipe extends CookingRecipe { * @param experience The experience given by this recipe * @param cookingTime The cooking time (in ticks) */ + @ApiStatus.Internal public FurnaceRecipe(@NotNull NamespacedKey key, @NotNull ItemStack result, @NotNull Material source, float experience, int cookingTime) { this(key, result, source, 0, experience, cookingTime); } - @Deprecated(since = "1.9") + @Deprecated(since = "1.9", forRemoval = true) public FurnaceRecipe(@NotNull NamespacedKey key, @NotNull ItemStack result, @NotNull Material source, int data, float experience, int cookingTime) { this(key, result, new RecipeChoice.MaterialChoice(Collections.singletonList(source)), experience, cookingTime); } @@ -58,6 +60,7 @@ public class FurnaceRecipe extends CookingRecipe { * @param experience The experience given by this recipe * @param cookingTime The cooking time (in ticks) */ + @ApiStatus.Internal public FurnaceRecipe(@NotNull NamespacedKey key, @NotNull ItemStack result, @NotNull RecipeChoice input, float experience, int cookingTime) { super(key, result, input, experience, cookingTime); } @@ -70,7 +73,7 @@ public class FurnaceRecipe extends CookingRecipe { * @deprecated use {@link #setInputChoice(RecipeChoice)} */ @NotNull - @Deprecated + @Deprecated(forRemoval = true) public FurnaceRecipe setInput(@NotNull MaterialData input) { return setInput(input.getItemType(), input.getData()); } @@ -90,7 +93,7 @@ public class FurnaceRecipe extends CookingRecipe { * @return The changed recipe, so you can chain calls. * @deprecated Magic value */ - @Deprecated(since = "1.6.2") + @Deprecated(since = "1.6.2", forRemoval = true) public FurnaceRecipe setInput(@NotNull Material input, int data) { return setInputChoice(new RecipeChoice.MaterialChoice(Collections.singletonList(input))); } diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemType.java b/paper-api/src/main/java/org/bukkit/inventory/ItemType.java index 3450c6350..6389f7610 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemType.java @@ -2404,7 +2404,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans * @deprecated creative categories no longer exist on the server */ @Nullable - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) CreativeCategory getCreativeCategory(); /** diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/MapMeta.java b/paper-api/src/main/java/org/bukkit/inventory/meta/MapMeta.java index 721164c26..29d53747e 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/MapMeta.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/MapMeta.java @@ -17,7 +17,6 @@ public interface MapMeta extends ItemMeta { * @return true if this has a map ID number. * @see #hasMapView() */ - //@Deprecated(since = "1.13.2") // Paper boolean hasMapId(); /** @@ -30,7 +29,6 @@ public interface MapMeta extends ItemMeta { * @return the map ID that is set * @see #getMapView() */ - // @Deprecated(since = "1.13.2") // Paper int getMapId(); /** 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 ada7b3d8f..02b0a3878 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 @@ -20,7 +20,7 @@ public interface PotionMeta extends ItemMeta { * @param data PotionData to set the base potion state to * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead. */ - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) void setBasePotionData(@Nullable PotionData data); /** @@ -30,7 +30,7 @@ public interface PotionMeta extends ItemMeta { * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead. */ @Nullable - @Deprecated(since = "1.20.6") + @Deprecated(since = "1.20.6", forRemoval = true) PotionData getBasePotionData(); /** diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/tags/CustomItemTagContainer.java b/paper-api/src/main/java/org/bukkit/inventory/meta/tags/CustomItemTagContainer.java index edf8698b6..e5f647105 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/tags/CustomItemTagContainer.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/tags/CustomItemTagContainer.java @@ -13,7 +13,7 @@ import org.jetbrains.annotations.Nullable; * {@link org.bukkit.persistence.PersistentDataHolder} API. Please use * {@link org.bukkit.persistence.PersistentDataHolder} instead of this. */ -@Deprecated(since = "1.14") +@Deprecated(since = "1.14", forRemoval = true) public interface CustomItemTagContainer { /** diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagAdapterContext.java b/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagAdapterContext.java index fae160e1c..1c4b1110c 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagAdapterContext.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagAdapterContext.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull; * @deprecated this API part has been replaced by {@link PersistentDataHolder}. * Please use {@link PersistentDataAdapterContext} instead of this. */ -@Deprecated(since = "1.14") +@Deprecated(since = "1.14", forRemoval = true) public interface ItemTagAdapterContext { /** diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagType.java b/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagType.java index 6288f6a09..41aa634b2 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/tags/ItemTagType.java @@ -46,7 +46,7 @@ import org.jetbrains.annotations.NotNull; * * @deprecated please use {@link PersistentDataType} as this part of the api is being replaced */ -@Deprecated(since = "1.14") +@Deprecated(since = "1.14", forRemoval = true) public interface ItemTagType { /* diff --git a/paper-api/src/main/java/org/bukkit/loot/LootContext.java b/paper-api/src/main/java/org/bukkit/loot/LootContext.java index 470f712e8..bdc21b3dd 100644 --- a/paper-api/src/main/java/org/bukkit/loot/LootContext.java +++ b/paper-api/src/main/java/org/bukkit/loot/LootContext.java @@ -64,7 +64,7 @@ public final class LootContext { * @return the looting level * @deprecated no longer functional */ - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public int getLootingModifier() { return lootingModifier; } @@ -136,7 +136,7 @@ public final class LootContext { * @deprecated no longer functional */ @NotNull - @Deprecated(since = "1.21") + @Deprecated(since = "1.21", forRemoval = true) public Builder lootingModifier(int modifier) { this.lootingModifier = modifier; return this; diff --git a/paper-api/src/main/java/org/bukkit/material/types/MushroomBlockTexture.java b/paper-api/src/main/java/org/bukkit/material/types/MushroomBlockTexture.java index 8e6e22cef..ca1b5d270 100644 --- a/paper-api/src/main/java/org/bukkit/material/types/MushroomBlockTexture.java +++ b/paper-api/src/main/java/org/bukkit/material/types/MushroomBlockTexture.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable; * Represents the different textured blocks of mushroom. * @deprecated use BlockData */ -@Deprecated // Paper +@Deprecated(forRemoval = true) public enum MushroomBlockTexture { /** @@ -82,7 +82,7 @@ public enum MushroomBlockTexture { * @return A byte containing the data value of this mushroom block face * @deprecated Magic value */ - @Deprecated(since = "1.9") + @Deprecated(since = "1.9", forRemoval = true) public byte getData() { return data; } @@ -105,7 +105,7 @@ public enum MushroomBlockTexture { * null if it doesn't exist * @deprecated Magic value */ - @Deprecated(since = "1.9") + @Deprecated(since = "1.9", forRemoval = true) @Nullable public static MushroomBlockTexture getByData(final byte data) { return BY_DATA.get(data); diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginAwareness.java b/paper-api/src/main/java/org/bukkit/plugin/PluginAwareness.java index 2fb458372..b4ccd6064 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginAwareness.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginAwareness.java @@ -21,7 +21,7 @@ public interface PluginAwareness { * * @deprecated all plugins are now assumed to be UTF-8 aware. */ - @Deprecated(since = "1.9") + @Deprecated(since = "1.9", forRemoval = true) UTF8, ; } diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java index 6dfd51996..0324ec640 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java @@ -1061,7 +1061,7 @@ public final class PluginDescriptionFile implements io.papermc.paper.plugin.conf * @return unused * @deprecated unused */ - @Deprecated(since = "1.7.2") + @Deprecated(since = "1.7.2", forRemoval = true) @Nullable public String getClassLoaderOf() { return classLoaderOf; diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java b/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java index e4cfdc80c..8f3b0bb55 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionEffectType.java @@ -271,7 +271,7 @@ public abstract class PotionEffectType implements Keyed, Translatable, net.kyori * @return duration modifier * @deprecated unused, always 1.0 */ - @Deprecated(since = "1.14") + @Deprecated(since = "1.14", forRemoval = true) public abstract double getDurationModifier(); /** diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java b/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java index 7acdeb905..35920c145 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java @@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull; /** * @deprecated only for backwards compatibility, PotionEffectTypeWrapper is no longer used. */ -@Deprecated(since = "1.20.3") +@Deprecated(since = "1.20.3", forRemoval = true) public abstract class PotionEffectTypeWrapper extends PotionEffectType { protected PotionEffectTypeWrapper() { } diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionType.java b/paper-api/src/main/java/org/bukkit/potion/PotionType.java index 912eb2f48..f7b485952 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionType.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionType.java @@ -150,7 +150,7 @@ public enum PotionType implements Keyed, io.papermc.paper.world.flag.FeatureDepe /** * @deprecated Do not use, interface will get removed, and the plugin won't run */ - @Deprecated(since = "1.20.2") + @Deprecated(since = "1.20.2", forRemoval = true) @ApiStatus.Internal public interface InternalPotionData { diff --git a/paper-api/src/main/java/org/bukkit/scoreboard/Criterias.java b/paper-api/src/main/java/org/bukkit/scoreboard/Criterias.java index 25bf2f94b..6a1cbd5a4 100644 --- a/paper-api/src/main/java/org/bukkit/scoreboard/Criterias.java +++ b/paper-api/src/main/java/org/bukkit/scoreboard/Criterias.java @@ -5,7 +5,7 @@ package org.bukkit.scoreboard; * * @deprecated use the constants declared in {@link Criteria} instead */ -@Deprecated(since = "1.19.2") +@Deprecated(since = "1.19.2", forRemoval = true) public final class Criterias { public static final String HEALTH = "health"; diff --git a/paper-api/src/main/java/org/bukkit/util/Consumer.java b/paper-api/src/main/java/org/bukkit/util/Consumer.java index 37deda46f..1b8646a22 100644 --- a/paper-api/src/main/java/org/bukkit/util/Consumer.java +++ b/paper-api/src/main/java/org/bukkit/util/Consumer.java @@ -10,7 +10,7 @@ package org.bukkit.util; // Bukkit developer note (NOT plugin developers): // NEVER use this consumer in the API. // API methods which use this consumer will be remapped to Java's consumer at runtime, resulting in an error. -@Deprecated(since = "1.20.2") +@Deprecated(since = "1.20.2", forRemoval = true) public interface Consumer extends java.util.function.Consumer { /** diff --git a/paper-api/src/test/java/org/bukkit/materials/MaterialDataTest.java b/paper-api/src/test/java/org/bukkit/materials/MaterialDataTest.java index 24a8ce438..9ecc4e695 100644 --- a/paper-api/src/test/java/org/bukkit/materials/MaterialDataTest.java +++ b/paper-api/src/test/java/org/bukkit/materials/MaterialDataTest.java @@ -22,7 +22,7 @@ import org.bukkit.material.WoodenStep; import org.bukkit.material.types.MushroomBlockTexture; import org.junit.jupiter.api.Test; -@Deprecated // Paper +@Deprecated(forRemoval = true) public class MaterialDataTest { @Test diff --git a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch index dcc561332..1e5f3e0f5 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch @@ -39,6 +39,14 @@ } public Optional> byKey(ResourceKey> key) { +@@ -184,6 +_,7 @@ + + @Nullable + public RecipeManager.ServerDisplayInfo getRecipeFromDisplay(RecipeDisplayId display) { ++ if (display.index() < 0 || display.index() >= this.allDisplays.size()) return null; // Paper + return this.allDisplays.get(display.index()); + } + @@ -199,6 +_,22 @@ Recipe recipe1 = Recipe.CODEC.parse(registries.createSerializationContext(JsonOps.INSTANCE), json).getOrThrow(JsonParseException::new); return new RecipeHolder<>(recipe, recipe1); 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 99beb7ec6..dfce118ec 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1889,11 +1889,6 @@ public final class CraftServer implements Server { this.saveConfig(); } - @Override - public boolean shouldSendChatPreviews() { - return false; - } - @Override public boolean isEnforcingSecureProfiles() { return this.getServer().enforceSecureProfile(); From 72f13f8bbbd03f2c63c2609092f4dc6586cdd888 Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Fri, 21 Mar 2025 13:50:58 -0300 Subject: [PATCH 190/203] [ci skip] Mention API Checks for CONTRIBUTING.md (#12315) --- CONTRIBUTING.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7805b0fba..c0975355b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -264,6 +264,40 @@ are assumed to be non-null by default. For less obvious placing such as on gener **For other classes**: Keep using both `@Nullable` and `@NotNull` from `org.jetbrains.annotations`. These will be replaced later. +### API checks + +When performing API-related checks where an exception needs to be thrown under specific conditions, you should use the `Preconditions` class. + +#### Checking Method Arguments +To validate method arguments, use `Preconditions#checkArgument`. This will throw an `IllegalArgumentException` if the condition is not met. +> Don't use Preconditions#checkNotNull, as it throws a NullPointerException, which makes it harder to determine whether the error was caused by an internal issue or invalid arguments. + +ex: +```java +@Override +public void sendMessage(Player player, Component message) { + Preconditions.checkArgument(player != null, "player cannot be null"); + Preconditions.checkArgument(player.isOnline(), "player %s must be online", player.getName()); + Preconditions.checkArgument(message != null, "message cannot be null"); + // rest of code +} +``` + +#### Checking Object State +To validate the state of an object inside a method, use `Preconditions#checkState`. This will throw an `IllegalStateException` if the condition is not met. +ex: +```java +private Player player; + +@Override +public void sendMessage(Component message) { + Preconditions.checkArgument(message != null, "message cannot be null"); + Preconditions.checkState(this.player != null, "player cannot be null"); + Preconditions.checkState(this.player.isOnline(), "player %s must be online", this.player.getName()); + // rest of code +} +``` + ## Access Transformers Sometimes, Vanilla code already contains a field, method, or type you want to access but the visibility is too low (e.g. a private field in an entity class). Paper can use access transformers From 7cc6cb5013d5680b359df6f092dc0e2f77462b4b Mon Sep 17 00:00:00 2001 From: TonytheMacaroni Date: Fri, 21 Mar 2025 12:51:09 -0400 Subject: [PATCH 191/203] Check for trailing input in ItemFactory#createItemStack (#12312) --- .../org/bukkit/craftbukkit/inventory/CraftItemFactory.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 10edd98d1..610318c8f 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 @@ -153,7 +153,9 @@ public final class CraftItemFactory implements ItemFactory { @Override public ItemStack createItemStack(String input) throws IllegalArgumentException { try { - ItemParser.ItemResult arg = new ItemParser(MinecraftServer.getDefaultRegistryAccess()).parse(new StringReader(input)); + StringReader reader = new StringReader(input); + ItemParser.ItemResult arg = new ItemParser(MinecraftServer.getDefaultRegistryAccess()).parse(reader); + Preconditions.checkArgument(!reader.canRead(), "Trailing input found when parsing ItemStack: %s", input); Item item = arg.item().value(); net.minecraft.world.item.ItemStack nmsItemStack = new net.minecraft.world.item.ItemStack(item); From f49d18df89ddce9f67963480410f2c7dddd4f308 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Fri, 21 Mar 2025 09:52:00 -0700 Subject: [PATCH 192/203] Add get/set customName to Skull block (#12302) --- build-data/paper.at | 1 + .../src/main/java/org/bukkit/block/Skull.java | 21 +++++++++++++++++++ .../bukkit/craftbukkit/block/CraftSkull.java | 14 +++++++++++++ 3 files changed, 36 insertions(+) diff --git a/build-data/paper.at b/build-data/paper.at index d1158d474..f9e03a951 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -605,6 +605,7 @@ public net.minecraft.world.level.block.entity.SculkSensorBlockEntity lastVibrati public net.minecraft.world.level.block.entity.SculkShriekerBlockEntity warningLevel public net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity openCount public net.minecraft.world.level.block.entity.SignBlockEntity playerWhoMayEdit +public net.minecraft.world.level.block.entity.SkullBlockEntity customName public net.minecraft.world.level.block.entity.SkullBlockEntity noteBlockSound public net.minecraft.world.level.block.entity.SkullBlockEntity owner public net.minecraft.world.level.block.entity.StructureBlockEntity author diff --git a/paper-api/src/main/java/org/bukkit/block/Skull.java b/paper-api/src/main/java/org/bukkit/block/Skull.java index d73137292..07033434f 100644 --- a/paper-api/src/main/java/org/bukkit/block/Skull.java +++ b/paper-api/src/main/java/org/bukkit/block/Skull.java @@ -1,5 +1,6 @@ package org.bukkit.block; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.OfflinePlayer; @@ -168,4 +169,24 @@ public interface Skull extends TileState { @Deprecated(since = "1.13", forRemoval = true) @Contract("_ -> fail") public void setSkullType(SkullType skullType); + + /** + * Get the custom name of skull. + *

This name is set when placing a skull item that has a custom name. + * This name is only carried back to the item when broken for player heads + * (skeleton/creeper heads will not retain the name).

+ * + * @return Custom name of skull + */ + public @Nullable Component customName(); + + /** + * Set the custom name of skull. + *

This name is set when placing a skull item that has a custom name. + * This name is only carried back to the item when broken for player heads + * (skeleton/creeper heads will not retain the name).

+ * + * @param customName Custom name of skull + */ + public void customName(@Nullable Component customName); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java index bae6f6132..4e6c1b2d2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -2,6 +2,8 @@ package org.bukkit.craftbukkit.block; import com.google.common.base.Preconditions; import com.mojang.authlib.GameProfile; +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; import net.minecraft.Util; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -216,4 +218,16 @@ public class CraftSkull extends CraftBlockEntityState implemen public CraftSkull copy(Location location) { return new CraftSkull(this, location); } + + @Override + public @Nullable Component customName() { + SkullBlockEntity snapshot = getSnapshot(); + return snapshot.customName == null ? null : PaperAdventure.asAdventure(snapshot.customName); + } + + @Override + public void customName(@Nullable Component customName) { + SkullBlockEntity snapshot = getSnapshot(); + snapshot.customName = customName == null ? null : PaperAdventure.asVanilla(customName); + } } From 894631f0d091a3de52aed4b6ec0c4f6c7584d697 Mon Sep 17 00:00:00 2001 From: Matthew Peters <76170255+FaintLocket424@users.noreply.github.com> Date: Fri, 21 Mar 2025 16:52:42 +0000 Subject: [PATCH 193/203] Make advancement ordering predictable (#12292) --- .../net/minecraft/server/PlayerAdvancements.java.patch | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index 0c15dfbc3..361c401ab 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -67,3 +67,12 @@ } }); } +@@ -247,7 +_,7 @@ + public void flushDirty(ServerPlayer serverPlayer) { + if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { + Map map = new HashMap<>(); +- Set set = new HashSet<>(); ++ Set set = new java.util.TreeSet<>(java.util.Comparator.comparing(adv -> adv.id().toString())); // Paper - Changed from HashSet to TreeSet ordered alphabetically. + Set set1 = new HashSet<>(); + + for (AdvancementNode advancementNode : this.rootsToUpdate) { From 2aad131e74f1cf5c8c7c06f57f39c8060561b6c3 Mon Sep 17 00:00:00 2001 From: Shane Freeder Date: Sun, 23 Mar 2025 18:31:39 +0000 Subject: [PATCH 194/203] Add config option for command spam whitelist --- .../0016-Moonrise-optimisation-patches.patch | 4 ++-- .../0026-Optional-per-player-mob-spawns.patch | 4 ++-- ...celling-PreCreatureSpawnEvent-with-per-pl.patch | 4 ++-- .../ServerGamePacketListenerImpl.java.patch | 10 ++++++---- .../src/main/java/org/spigotmc/SpigotConfig.java | 14 ++++++++++++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index c458f8f14..7dfc137ed 100644 --- a/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -27496,7 +27496,7 @@ index d1f235ebd835f58cf0c703c3a64d29825d98e183..080091efc19bc768bb9a660f366c42e8 } diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index f054ea710108e5017bc48fdda5f180a04f5b55e2..f44600604a7bf68c990cd74a1ac2d7900ff6e88e 100644 +index 0bb610f12e3ddda649ecb5ad62ffdc7bfd243223..19428343b37c9b739b3d28984d52e257f85f253f 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team; @@ -27508,7 +27508,7 @@ index f054ea710108e5017bc48fdda5f180a04f5b55e2..f44600604a7bf68c990cd74a1ac2d790 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; -@@ -388,6 +388,36 @@ public class ServerPlayer extends Player { +@@ -395,6 +395,36 @@ public class ServerPlayer extends Player { public @Nullable String clientBrandName = null; // Paper - Brand support public 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 diff --git a/paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch b/paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch index 8aa76f34a..29b33f230 100644 --- a/paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch +++ b/paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch @@ -78,10 +78,10 @@ index 87d4291a3944f706a694536da6de0f28c548ab8d..5576bf1d1d70ab7a010653d3207909b5 profiler.popPush("spawnAndTick"); boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 1fe212e8584c177b49e83f29b1a869b534914348..cd6b5176f34248f844f0e591875701bd08f455ce 100644 +index 02fb30a3adf92de0795aee213caf94a228b01ca0..67f6e40216e0be063a3cfb61427f095f7c74d785 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -368,6 +368,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -375,6 +375,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc public boolean queueHealthUpdatePacket; public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; // Paper end - cancellable death event diff --git a/paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index 0e16d7da2..e098cf936 100644 --- a/paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -60,10 +60,10 @@ index 5576bf1d1d70ab7a010653d3207909b5de867e70..6540b2d6a1062d883811ce240c49d30d 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 cd6b5176f34248f844f0e591875701bd08f455ce..f347ff8d863f4bcef46604c757de112cb3fe445c 100644 +index 67f6e40216e0be063a3cfb61427f095f7c74d785..3de65c4025be91d938a350c884975cb6edc234d3 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -372,6 +372,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -379,6 +379,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 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 c938c7bb9..ef655fc32 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 @@ -1561,7 +1561,7 @@ } return optional; -@@ -1451,22 +_,155 @@ +@@ -1451,22 +_,157 @@ return false; } @@ -1707,9 +1707,11 @@ + // Spigot start - spam exclusions + private void detectRateSpam(String message) { + // CraftBukkit start - replaced with thread safe throttle -+ for (String exclude : org.spigotmc.SpigotConfig.spamExclusions) { -+ if (exclude != null && message.startsWith(exclude)) { -+ return; ++ if (org.spigotmc.SpigotConfig.enableSpamExclusions) { ++ for (String exclude : org.spigotmc.SpigotConfig.spamExclusions) { ++ if (exclude != null && message.startsWith(exclude)) { ++ return; ++ } + } + } + // Spigot end diff --git a/paper-server/src/main/java/org/spigotmc/SpigotConfig.java b/paper-server/src/main/java/org/spigotmc/SpigotConfig.java index e0d4222a9..d1351ed25 100644 --- a/paper-server/src/main/java/org/spigotmc/SpigotConfig.java +++ b/paper-server/src/main/java/org/spigotmc/SpigotConfig.java @@ -242,9 +242,23 @@ public class SpigotConfig { SpigotConfig.playerShuffle = SpigotConfig.getInt("settings.player-shuffle", 0); } + public static boolean enableSpamExclusions = false; public static List spamExclusions; private static void spamExclusions() { SpigotConfig.spamExclusions = SpigotConfig.getList("commands.spam-exclusions", List.of("/skill")); + Object enabled = SpigotConfig.config.get("commands.enable-spam-exclusions"); + if (enabled instanceof Boolean value) { + SpigotConfig.enableSpamExclusions = value; + } else { + if (spamExclusions.size() == 1 && spamExclusions.getFirst().equals("/skill")) { + SpigotConfig.enableSpamExclusions = false; + SpigotConfig.set("commands.enable-spam-exclusions", false); + } else { + SpigotConfig.enableSpamExclusions = true; + SpigotConfig.set("commands.enable-spam-exclusions", true); + } + } + } public static boolean silentCommandBlocks; From bb3b7e697965740a36c0a20139127167e2f857a0 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 23 Mar 2025 22:33:28 +0100 Subject: [PATCH 195/203] Fix annotation mistakes --- .../java/org/bukkit/event/entity/EntityShootBowEvent.java | 4 ++-- .../src/main/java/org/bukkit/inventory/FurnaceRecipe.java | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java b/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java index d02fa4358..55aa26b89 100644 --- a/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java @@ -7,7 +7,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; -import org.checkerframework.checker.signature.qual.InternalForm; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,7 +50,7 @@ public class EntityShootBowEvent extends EntityEvent implements Cancellable { } // Paper end - @InternalForm + @ApiStatus.Internal public EntityShootBowEvent(@NotNull final LivingEntity shooter, @Nullable final ItemStack bow, @Nullable final ItemStack consumable, @NotNull final Entity projectile, @NotNull final EquipmentSlot hand, final float force, final boolean consumeItem) { super(shooter); this.bow = bow; diff --git a/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java b/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java index c922da90e..b8b7176a0 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java +++ b/paper-api/src/main/java/org/bukkit/inventory/FurnaceRecipe.java @@ -4,7 +4,6 @@ import java.util.Collections; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.material.MaterialData; -import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -41,7 +40,6 @@ public class FurnaceRecipe extends CookingRecipe { * @param experience The experience given by this recipe * @param cookingTime The cooking time (in ticks) */ - @ApiStatus.Internal public FurnaceRecipe(@NotNull NamespacedKey key, @NotNull ItemStack result, @NotNull Material source, float experience, int cookingTime) { this(key, result, source, 0, experience, cookingTime); } @@ -60,7 +58,6 @@ public class FurnaceRecipe extends CookingRecipe { * @param experience The experience given by this recipe * @param cookingTime The cooking time (in ticks) */ - @ApiStatus.Internal public FurnaceRecipe(@NotNull NamespacedKey key, @NotNull ItemStack result, @NotNull RecipeChoice input, float experience, int cookingTime) { super(key, result, input, experience, cookingTime); } From 058455e4ca9114a9860dfe2c37558f78993e9055 Mon Sep 17 00:00:00 2001 From: Miles <81843550+Y2Kwastaken@users.noreply.github.com> Date: Sun, 23 Mar 2025 17:46:10 -0500 Subject: [PATCH 196/203] InventoryView QOL open method (#12282) * Add QOL open method to InventoryView * Check to ensure the opening isn't a InventoryMenu, allow HorseMenus * Fix instanceof against API instaed of AbstractContainerMenu * [ci skip] Remove suggested comment --- build-data/paper.at | 1 + .../java/org/bukkit/inventory/InventoryView.java | 5 +++++ .../bukkit/craftbukkit/entity/CraftHumanEntity.java | 12 +++++++++++- .../inventory/CraftAbstractInventoryView.java | 5 +++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/build-data/paper.at b/build-data/paper.at index f9e03a951..90f4e4168 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -491,6 +491,7 @@ public net.minecraft.world.inventory.AnvilMenu repairItemCountCost public net.minecraft.world.inventory.BrewingStandMenu brewingStandData public net.minecraft.world.inventory.CraftingMenu access public net.minecraft.world.inventory.DispenserMenu dispenser +public net.minecraft.world.inventory.HorseInventoryMenu horse public net.minecraft.world.inventory.HorseInventoryMenu SLOT_BODY_ARMOR public net.minecraft.world.inventory.MerchantContainer selectionHint public net.minecraft.world.inventory.Slot slot 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 5c258b607..46f5f5017 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/InventoryView.java +++ b/paper-api/src/main/java/org/bukkit/inventory/InventoryView.java @@ -242,6 +242,11 @@ public interface InventoryView { @NotNull public InventoryType.SlotType getSlotType(int slot); + /** + * Opens the inventory view. + */ + void open(); + /** * Closes the inventory view. */ 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 a39615754..ba3b2a60d 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 @@ -11,6 +11,7 @@ import java.util.function.Consumer; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.game.ClientboundHorseScreenOpenPacket; import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; import net.minecraft.network.protocol.game.ServerboundContainerClosePacket; import net.minecraft.resources.ResourceLocation; @@ -24,6 +25,8 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FireworkRocketEntity; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.HorseInventoryMenu; +import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MerchantMenu; import net.minecraft.world.item.ItemCooldowns; @@ -455,6 +458,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { AbstractContainerMenu container; if (inventory instanceof CraftInventoryView) { container = ((CraftInventoryView) inventory).getHandle(); + Preconditions.checkArgument(!(container instanceof InventoryMenu), "Can not open player's InventoryView"); } else { container = new CraftContainer(inventory, this.getHandle(), player.nextContainerCounter()); } @@ -481,7 +485,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { if (adventure$title == null) adventure$title = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(inventory.getTitle()); // Paper if (result.getFirst() != null) adventure$title = result.getFirst(); // Paper - Add titleOverride to InventoryOpenEvent //player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, CraftChatMessage.fromString(title)[0])); // Paper - comment - if (!player.isImmobile()) player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); // Paper - Prevent opening inventories when frozen + if (!player.isImmobile()) { + if (container instanceof HorseInventoryMenu horse) { + player.connection.send(new ClientboundHorseScreenOpenPacket(horse.containerId, horse.horse.getInventoryColumns(), horse.horse.getId())); + } else { + player.connection.send(new ClientboundOpenScreenPacket(container.containerId, windowType, io.papermc.paper.adventure.PaperAdventure.asVanilla(adventure$title))); + } + } player.containerMenu = container; player.initMenu(container); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java index 6331be478..8697adc63 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java @@ -208,6 +208,11 @@ public abstract class CraftAbstractInventoryView implements InventoryView { return type; } + @Override + public void open() { + getPlayer().openInventory(this); + } + @Override public void close() { this.getPlayer().closeInventory(); From f225858235625dd7a9eab7e1e0f02e44690095ca Mon Sep 17 00:00:00 2001 From: Pedro <3602279+Doc94@users.noreply.github.com> Date: Sun, 23 Mar 2025 20:20:14 -0300 Subject: [PATCH 197/203] Fix firework entity not being removed when FireworkExplodeEvent is cancelled (#12268) * Fix Firework not removed when FireworkExplodeEvent is canceled * JUnit require pass null * tweaks --- .../0003-Entity-Activation-Range-2.0.patch | 16 ++++++++-------- .../projectile/FireworkRocketEntity.java.patch | 18 +++++++++--------- .../craftbukkit/event/CraftEventFactory.java | 9 ++++++--- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch index 11abde7c3..944456687 100644 --- a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch @@ -366,7 +366,7 @@ index d95413af04121fe91ca0f3b0c70025b9808acef9..ad665c7535c615d2b03a3e7864be435f import org.slf4j.Logger; diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index cdb4d313eb33c049c8467fe5d31fb0d671737768..40b799fd90b0db13bdaa8834c021f5ca8f25ce10 100644 +index f45fb8ddb08d82ce76018b5a5c4fce5b3b319559..12f0dc36c5adcdbd9e1dad5f8512ac184da3960f 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java @@ -551,6 +551,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @@ -476,7 +476,7 @@ index 24735284fda151414d99faad401d25ba60995f9a..23b342cc31c7e72ade0e1ccad86a9ccf public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 54cf80831372d102e8d2966ac104678caebdf336..d89c3949e16ff6cb0374da29ec6731d854b5f105 100644 +index 2facc7ad69bfe28c2f928a026ba5ab37387ab039..6256d7f8f4ee8bd4e3673b4e069af5cc0069c8f2 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -381,6 +381,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @@ -533,7 +533,7 @@ index 54cf80831372d102e8d2966ac104678caebdf336..d89c3949e16ff6cb0374da29ec6731d8 movement = this.maybeBackOffFromEdge(movement, type); Vec3 vec3 = this.collide(movement); diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index bf5fd2a6c8630ea2bb06881d4d365dda9a4e90ea..4713c29cc2add476f568163a29cb297f5d1049df 100644 +index e0c310d970a687945b6a771b4ecb94044128c33c..4546aca8e2e144ec207653c713fc49f849908827 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java @@ -3103,6 +3103,14 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -552,7 +552,7 @@ index bf5fd2a6c8630ea2bb06881d4d365dda9a4e90ea..4713c29cc2add476f568163a29cb297f public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index f7d69db61d1293510428ae275e8a50571dde5ddf..1ed07fd23985a6bf8cf8300f74c92b7531a79fc6 100644 +index e12b47ca5eeb842bae606c0c7a8e3e4cf7d468a9..e330bf990e4874baed1b21cd8c9b44d66ec5b823 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java @@ -215,6 +215,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab @@ -764,7 +764,7 @@ index c1e09e701757a300183b62d343ded03033e63aa7..56574f8ef879159edc0114da09300143 public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -index 7c0862c50b44555fb27ce7dc46f4ec95a3eb0022..774ca9e0b56fd175ae246051de762d0c4256ca58 100644 +index a3e4605a81eeaca77cc3a3ab937b75a415d83037..c7ae41b2cbc1eb85a6eb9c16813bd326fb8f49f0 100644 --- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java @@ -102,6 +102,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { @@ -776,11 +776,11 @@ index 7c0862c50b44555fb27ce7dc46f4ec95a3eb0022..774ca9e0b56fd175ae246051de762d0c + public void inactiveTick() { + this.life++; + if (this.life > this.lifetime && this.level() instanceof ServerLevel serverLevel) { -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { ++ // Paper start - Call FireworkExplodeEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this)) { + this.explode(serverLevel); + } -+ // CraftBukkit end ++ // Paper end - Call FireworkExplodeEvent + } + super.inactiveTick(); + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch index f0049b5ab..b776903e2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch @@ -22,11 +22,11 @@ if (this.life > this.lifetime && this.level() instanceof ServerLevel serverLevel) { - this.explode(serverLevel); -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { ++ // Paper start - Call FireworkExplodeEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this)) { + this.explode(serverLevel); + } -+ // CraftBukkit end ++ // Paper end - Call FireworkExplodeEvent } } @@ -43,11 +43,11 @@ super.onHitEntity(result); if (this.level() instanceof ServerLevel serverLevel) { - this.explode(serverLevel); -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { ++ // Paper start - Call FireworkExplodeEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this)) { + this.explode(serverLevel); + } -+ // CraftBukkit end ++ // Paper end - Call FireworkExplodeEvent } } @@ -56,11 +56,11 @@ this.level().getBlockState(blockPos).entityInside(this.level(), blockPos, this); if (this.level() instanceof ServerLevel serverLevel && this.hasExplosion()) { - this.explode(serverLevel); -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) { ++ // Paper start - Call FireworkExplodeEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this)) { + this.explode(serverLevel); + } -+ // CraftBukkit end ++ // Paper end - Call FireworkExplodeEvent } super.onHitBlock(result); 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 57c3f8531..bbf44c44c 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 @@ -1762,10 +1762,13 @@ public class CraftEventFactory { return (Cancellable) event; } - public static FireworkExplodeEvent callFireworkExplodeEvent(FireworkRocketEntity firework) { + public static boolean callFireworkExplodeEvent(FireworkRocketEntity firework) { FireworkExplodeEvent event = new FireworkExplodeEvent((Firework) firework.getBukkitEntity()); - firework.level().getCraftServer().getPluginManager().callEvent(event); - return event; + if (!event.callEvent()) { + firework.discard(null); + return false; + } + return true; } public static PrepareAnvilEvent callPrepareAnvilEvent(AnvilView view, ItemStack item) { From 7819df10a48bcff04d616b99a6941b81e96530d6 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Sun, 23 Mar 2025 16:33:34 -0700 Subject: [PATCH 198/203] Add getHeight method to ChunkData (#12311) --- .../java/org/bukkit/generator/ChunkGenerator.java | 14 ++++++++++++++ .../craftbukkit/generator/CraftChunkData.java | 11 ++++++++++- .../craftbukkit/generator/OldCraftChunkData.java | 6 ++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/paper-api/src/main/java/org/bukkit/generator/ChunkGenerator.java b/paper-api/src/main/java/org/bukkit/generator/ChunkGenerator.java index 4e8d0b2f7..8aca905b0 100644 --- a/paper-api/src/main/java/org/bukkit/generator/ChunkGenerator.java +++ b/paper-api/src/main/java/org/bukkit/generator/ChunkGenerator.java @@ -14,6 +14,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.material.MaterialData; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; /** * A chunk generator is responsible for the initial shaping of an entire @@ -777,5 +778,18 @@ public abstract class ChunkGenerator { */ @Deprecated(since = "1.8.8") public byte getData(int x, int y, int z); + + /** + * Get the current height of a position in the chunk data. + *

This will differ based on which state generation of the chunk is currently at. + * If for example the chunk is in the generate surface stage, + * this will return what was already generated in the noise stage.

+ * + * @param heightMap Heightmap to determine where to grab height + * @param x the x location in the chunk from 0-15 inclusive + * @param z the z location in the chunk from 0-15 inclusive + * @return Y coordinate at highest position + */ + int getHeight(@NotNull HeightMap heightMap, @Range(from = 0L, to = 15L) int x, @Range(from = 0L, to = 15L) int z); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java index 0fb580530..679cc7a7d 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java @@ -8,12 +8,13 @@ import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; +import org.bukkit.HeightMap; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.CraftHeightMap; import org.bukkit.craftbukkit.block.CraftBiome; -import org.bukkit.craftbukkit.block.CraftBlockType; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.generator.ChunkGenerator; @@ -180,4 +181,12 @@ public final class CraftChunkData implements ChunkGenerator.ChunkData { access.removeBlockEntity(blockPosition); } } + + @Override + public int getHeight(final HeightMap heightMap, final int x, final int z) { + Preconditions.checkArgument(heightMap != null, "HeightMap cannot be null"); + Preconditions.checkArgument(x >= 0 && x <= 15 && z >= 0 && z <= 15, "Cannot get height outside of a chunks bounds, must be between 0 and 15, got x: %s, z: %s", x, z); + + return getHandle().getHeight(CraftHeightMap.toNMS(heightMap), x, z); + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java index 719fe4cbe..78c302581 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/OldCraftChunkData.java @@ -8,6 +8,7 @@ import net.minecraft.core.Registry; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.LevelChunkSection; +import org.bukkit.HeightMap; import org.bukkit.Material; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -200,4 +201,9 @@ public final class OldCraftChunkData implements ChunkGenerator.ChunkData { Set getLights() { return this.lights; } + + @Override + public int getHeight(HeightMap heightMap, final int x, final int z) { + throw new UnsupportedOperationException("Unsupported, in older chunk generator api"); + } } From 37b9ca1f90d4da9d1e8dc4a94a5357835babda4f Mon Sep 17 00:00:00 2001 From: Strokkur24 <133226102+Strokkur424@users.noreply.github.com> Date: Mon, 24 Mar 2025 00:37:48 +0100 Subject: [PATCH 199/203] Add flush parameter to World#save (#12330) --- paper-api/src/main/java/org/bukkit/World.java | 16 +++++++++++----- .../java/org/bukkit/craftbukkit/CraftWorld.java | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index 96120ce0e..bff01411f 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -1,9 +1,7 @@ package org.bukkit; -import java.io.File; import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilder; -import org.bukkit.generator.ChunkGenerator; - +import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -2410,9 +2408,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient public BiomeProvider getBiomeProvider(); /** - * Saves world to disk + * Saves the world to disk */ - public void save(); + default void save() { + save(false); + } + + /** + * Saves the world to disk + * @param flush Whether to wait for the chunk writer to finish + */ + void save(boolean flush); /** * Gets a list of all applied {@link BlockPopulator}s for this World 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 1439d2821..a92e08776 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1264,13 +1264,13 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Paper end @Override - public void save() { + public void save(boolean flush) { org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot this.server.checkSaveState(); boolean oldSave = this.world.noSave; this.world.noSave = false; - this.world.save(null, false, false); + this.world.save(null, flush, false); this.world.noSave = oldSave; } From 515e12ca2d2b9ecb4d9222b49c6ed7c07d4f05e4 Mon Sep 17 00:00:00 2001 From: Tamion <70228790+notTamion@users.noreply.github.com> Date: Mon, 24 Mar 2025 00:38:25 +0100 Subject: [PATCH 200/203] Check if BUNDLE_CONTENTS is present in InventoryClickEvent (#12321) --- .../network/ServerGamePacketListenerImpl.java.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 ef655fc32..6ce6f262a 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 @@ -2104,7 +2104,7 @@ + ItemStack cursor = this.player.containerMenu.getCarried(); + if (clickedItem.isEmpty()) { + if (!cursor.isEmpty()) { -+ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() != 0) { ++ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && cursor.has(DataComponents.BUNDLE_CONTENTS) && packet.getButtonNum() != 0) { + action = cursor.get(DataComponents.BUNDLE_CONTENTS).isEmpty() ? InventoryAction.NOTHING : InventoryAction.PLACE_FROM_BUNDLE; + } else { + action = packet.getButtonNum() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; @@ -2112,7 +2112,7 @@ + } + } else if (slot.mayPickup(this.player)) { + if (cursor.isEmpty()) { -+ if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() != 0) { ++ if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && slot.getItem().has(DataComponents.BUNDLE_CONTENTS) && packet.getButtonNum() != 0) { + action = slot.getItem().get(DataComponents.BUNDLE_CONTENTS).isEmpty() ? InventoryAction.NOTHING : InventoryAction.PICKUP_FROM_BUNDLE; + } else { + action = packet.getButtonNum() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; @@ -2132,7 +2132,7 @@ + action = InventoryAction.PLACE_SOME; + } + } else if (cursor.getCount() <= slot.getMaxStackSize()) { -+ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() == 0) { ++ if (cursor.getItem() instanceof net.minecraft.world.item.BundleItem && cursor.has(DataComponents.BUNDLE_CONTENTS) && packet.getButtonNum() == 0) { + int toPickup = cursor.get(DataComponents.BUNDLE_CONTENTS).getMaxAmountToAdd(slot.getItem()); + if (toPickup >= slot.getItem().getCount()) { + action = InventoryAction.PICKUP_ALL_INTO_BUNDLE; @@ -2141,7 +2141,7 @@ + } else { + action = InventoryAction.PICKUP_SOME_INTO_BUNDLE; + } -+ } else if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && packet.getButtonNum() == 0) { ++ } else if (slot.getItem().getItem() instanceof net.minecraft.world.item.BundleItem && slot.getItem().has(DataComponents.BUNDLE_CONTENTS) && packet.getButtonNum() == 0) { + int toPickup = slot.getItem().get(DataComponents.BUNDLE_CONTENTS).getMaxAmountToAdd(cursor); + if (toPickup >= cursor.getCount()) { + action = InventoryAction.PLACE_ALL_INTO_BUNDLE; From 5a6ab97be6bdc8231582e15112c7a847a8800549 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Sun, 23 Mar 2025 16:55:15 -0700 Subject: [PATCH 201/203] Add config to remove player as vehicle restriction in /ride (#12327) --- .../minecraft/server/commands/RideCommand.java.patch | 11 +++++++++++ .../paper/configuration/GlobalConfiguration.java | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch diff --git a/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch new file mode 100644 index 000000000..3e3691904 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/commands/RideCommand.java ++++ b/net/minecraft/server/commands/RideCommand.java +@@ -58,7 +_,7 @@ + Entity vehicle1 = target.getVehicle(); + if (vehicle1 != null) { + throw ERROR_ALREADY_RIDING.create(target.getDisplayName(), vehicle1.getDisplayName()); +- } else if (vehicle.getType() == EntityType.PLAYER) { ++ } else if (vehicle.getType() == EntityType.PLAYER && !io.papermc.paper.configuration.GlobalConfiguration.get().commands.rideCommandAllowPlayerAsVehicle) { // Paper - allow player as vehicle + throw ERROR_MOUNTING_PLAYER.create(); + } else if (target.getSelfAndPassengers().anyMatch(passenger -> passenger == vehicle)) { + throw ERROR_MOUNTING_LOOP.create(); 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 e3a7e6937..8b70a8e9b 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 @@ -12,7 +12,6 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Items; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.spongepowered.configurate.objectmapping.ConfigSerializable; @@ -202,6 +201,8 @@ public class GlobalConfiguration extends ConfigurationPart { public class Commands extends ConfigurationPart { public boolean suggestPlayerNamesWhenNullTabCompletions = true; public boolean timeCommandAffectsAllWorlds = false; + @Comment("Allow mounting entities to a player in the Vanilla '/ride' command.") + public boolean rideCommandAllowPlayerAsVehicle = false; } public Logging logging; From c467df95a29e6c3d42b7e6f49513e924f9ba2ece Mon Sep 17 00:00:00 2001 From: TonytheMacaroni Date: Sun, 23 Mar 2025 20:12:57 -0400 Subject: [PATCH 202/203] Add ItemStack#copyDataFrom (#12224) --- .../papermc/paper/registry/RegistryKey.java | 2 +- .../java/org/bukkit/inventory/ItemStack.java | 26 ++++++++++++++ .../craftbukkit/inventory/CraftItemStack.java | 34 +++++++++++++++---- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java index 0238eb155..49e508c4e 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/RegistryKey.java @@ -79,7 +79,7 @@ public sealed interface RegistryKey extends Keyed permits RegistryKeyImpl { RegistryKey BLOCK = create("block"); /** * @apiNote use preferably only in the context of registry entries. - * @see io.papermc.paper.registry.data + * @see io.papermc.paper.registry.keys.ItemTypeKeys */ @ApiStatus.Experimental // Paper - already required for registry builders RegistryKey ITEM = create("item"); 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 dc50f83e9..aad9b078a 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemStack.java @@ -6,6 +6,7 @@ import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Predicate; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -1306,6 +1307,31 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat this.craftDelegate.resetData(type); } + /** + * Copies component values and component removals from the provided ItemStack. + *

+ * Example: + *

{@code
+     * Set types = Set.of(
+     *     DataComponentTypes.CONSUMABLE,
+     *     DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE,
+     *     DataComponentTypes.RARITY
+     * );
+     *
+     * ItemStack source = ItemStack.of(Material.ENCHANTED_GOLDEN_APPLE);
+     * ItemStack target = ItemStack.of(Material.GOLDEN_CARROT);
+     *
+     * target.copyDataFrom(source, types::contains);
+     * }
+ * + * @param source the item stack to copy from + * @param filter predicate for which components to copy + */ + @org.jetbrains.annotations.ApiStatus.Experimental + public void copyDataFrom(final @NotNull ItemStack source, final @NotNull Predicate filter) { + this.craftDelegate.copyDataFrom(source, filter); + } + /** * Checks if the data component type is overridden from the default for the * item type. 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 a6668ae29..d3dc1f7fe 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 @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.function.Consumer; +import java.util.function.Predicate; import net.kyori.adventure.text.Component; import net.minecraft.advancements.critereon.ItemPredicate; import net.minecraft.advancements.critereon.MinMaxBounds; @@ -15,6 +16,7 @@ import net.minecraft.core.HolderSet; import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentPredicate; +import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.PatchedDataComponentMap; import net.minecraft.nbt.CompoundTag; @@ -54,7 +56,7 @@ public final class CraftItemStack extends ItemStack { if (bukkit instanceof final CraftItemStack craftItemStack) { return craftItemStack; } else { - return (CraftItemStack) API_ITEM_STACK_CRAFT_DELEGATE_FIELD.get(bukkit); + return (CraftItemStack) API_ITEM_STACK_CRAFT_DELEGATE_FIELD.get(bukkit); } } @@ -71,12 +73,12 @@ public final class CraftItemStack extends ItemStack { @Override public boolean equals(final Object obj) { - if (!(obj instanceof final org.bukkit.inventory.ItemStack bukkit)) return false; + if (!(obj instanceof final ItemStack bukkit)) return false; final CraftItemStack craftStack = getCraftStack(bukkit); if (this.handle == craftStack.handle) return true; - else if (this.handle == null || craftStack.handle == null) return false; - else if (this.handle.isEmpty() && craftStack.handle.isEmpty()) return true; - else return net.minecraft.world.item.ItemStack.matches(this.handle, craftStack.handle); + if (this.handle == null || craftStack.handle == null) return false; + if (this.handle.isEmpty() && craftStack.handle.isEmpty()) return true; + return net.minecraft.world.item.ItemStack.matches(this.handle, craftStack.handle); } // Paper end @@ -648,14 +650,32 @@ public final class CraftItemStack extends ItemStack { this.handle.set(nms, nmsValue); } + @Override + public void copyDataFrom(final ItemStack source, final Predicate filter) { + Preconditions.checkArgument(source != null, "source cannot be null"); + Preconditions.checkArgument(filter != null, "filter cannot be null"); + if (this.isEmpty() || source.isEmpty()) { + return; + } + + final Predicate> nmsFilter = nms -> filter.test(io.papermc.paper.datacomponent.PaperDataComponentType.minecraftToBukkit(nms)); + net.minecraft.world.item.ItemStack sourceNmsStack = getCraftStack(source).handle; + this.handle.applyComponents(sourceNmsStack.getPrototype().filter(nmsType -> { + return !sourceNmsStack.hasNonDefault(nmsType) && nmsFilter.test(nmsType); + })); + + final DataComponentPatch.SplitResult split = sourceNmsStack.getComponentsPatch().split(); + this.handle.applyComponents(split.added().filter(nmsFilter)); + split.removed().stream().filter(nmsFilter).forEach(this.handle::remove); + } + @Override public boolean isDataOverridden(final io.papermc.paper.datacomponent.DataComponentType type) { if (this.isEmpty()) { return false; } final net.minecraft.core.component.DataComponentType nms = io.papermc.paper.datacomponent.PaperDataComponentType.bukkitToMinecraft(type); - // maybe a more efficient way is to expose the "patch" map in PatchedDataComponentMap and just check if the type exists as a key - return !java.util.Objects.equals(this.handle.get(nms), this.handle.getPrototype().get(nms)); + return this.handle.hasNonDefault(nms); } @Override From 9b1798d6438107fdf0d5939b79a8cf71f4d16e2c Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Thu, 27 Mar 2025 14:22:38 +0100 Subject: [PATCH 203/203] Simplify custom payload handling (#12347) --- build-data/paper.at | 2 +- .../common/custom/DiscardedPayload.java.patch | 13 ++- .../ServerCommonPacketListenerImpl.java.patch | 90 ++++++++++--------- .../inventory/HorseInventoryMenu.java.patch | 2 +- .../craftbukkit/entity/CraftPlayer.java | 7 +- 5 files changed, 59 insertions(+), 55 deletions(-) diff --git a/build-data/paper.at b/build-data/paper.at index 90f4e4168..e5c60c62d 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -491,8 +491,8 @@ public net.minecraft.world.inventory.AnvilMenu repairItemCountCost public net.minecraft.world.inventory.BrewingStandMenu brewingStandData public net.minecraft.world.inventory.CraftingMenu access public net.minecraft.world.inventory.DispenserMenu dispenser -public net.minecraft.world.inventory.HorseInventoryMenu horse public net.minecraft.world.inventory.HorseInventoryMenu SLOT_BODY_ARMOR +public net.minecraft.world.inventory.HorseInventoryMenu horse public net.minecraft.world.inventory.MerchantContainer selectionHint public net.minecraft.world.inventory.Slot slot public net.minecraft.world.item.AdventureModePredicate predicates diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/common/custom/DiscardedPayload.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/common/custom/DiscardedPayload.java.patch index 38c086da6..d0e27d159 100644 --- a/paper-server/patches/sources/net/minecraft/network/protocol/common/custom/DiscardedPayload.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/protocol/common/custom/DiscardedPayload.java.patch @@ -1,21 +1,26 @@ --- a/net/minecraft/network/protocol/common/custom/DiscardedPayload.java +++ b/net/minecraft/network/protocol/common/custom/DiscardedPayload.java -@@ -4,13 +_,14 @@ +@@ -4,13 +_,19 @@ import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; -public record DiscardedPayload(ResourceLocation id) implements CustomPacketPayload { -+public record DiscardedPayload(ResourceLocation id, io.netty.buffer.ByteBuf data) implements CustomPacketPayload { // CraftBukkit - store data ++public record DiscardedPayload(ResourceLocation id, byte[] data) implements CustomPacketPayload { // Paper - store data public static StreamCodec codec(ResourceLocation id, int maxSize) { - return CustomPacketPayload.codec((value, output) -> {}, buffer -> { + return CustomPacketPayload.codec((value, output) -> { -+ output.writeBytes(value.data); // CraftBukkit - serialize ++ // Paper start ++ // Always write data ++ output.writeBytes(value.data); + }, buffer -> { int i = buffer.readableBytes(); if (i >= 0 && i <= maxSize) { - buffer.skipBytes(i); - return new DiscardedPayload(id); -+ return new DiscardedPayload(id, buffer.readBytes(i)); // CraftBukkit ++ final byte[] data = new byte[i]; ++ buffer.readBytes(data); ++ return new DiscardedPayload(id, data); ++ // Paper end } else { throw new IllegalArgumentException("Payload may not be larger than " + maxSize + " bytes"); } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index af6cdd217..74d485b66 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -95,7 +95,7 @@ } } -@@ -88,30 +_,119 @@ +@@ -88,30 +_,123 @@ public void handlePong(ServerboundPongPacket packet) { } @@ -105,64 +105,68 @@ @Override public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { - } -+ // CraftBukkit start -+ // Paper start - Brand support ++ // Paper start + if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload(String brand)) { + this.player.clientBrandName = brand; + } -+ // Paper end - Brand support ++ + if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) { + return; + } -+ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -+ net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id(); -+ io.netty.buffer.ByteBuf payload = discardedPayload.data(); + -+ if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_REGISTER)) { -+ try { -+ String channels = payload.toString(com.google.common.base.Charsets.UTF_8); -+ for (String channel : channels.split("\0")) { -+ this.getCraftPlayer().addChannel(channel); -+ } -+ } catch (Exception ex) { -+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't register custom payload", ex); -+ this.disconnect(Component.literal("Invalid payload REGISTER!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause -+ } -+ } else if (identifier.equals(ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER)) { -+ try { -+ String channels = payload.toString(com.google.common.base.Charsets.UTF_8); -+ for (String channel : channels.split("\0")) { -+ this.getCraftPlayer().removeChannel(channel); -+ } -+ } catch (Exception ex) { -+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't unregister custom payload", ex); -+ this.disconnect(Component.literal("Invalid payload UNREGISTER!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause -+ } -+ } else { -+ try { -+ byte[] data = new byte[payload.readableBytes()]; -+ payload.readBytes(data); -+ // Paper start - Brand support; Retain this incase upstream decides to 'break' the new mechanism in favour of backwards compat... -+ if (identifier.equals(MINECRAFT_BRAND)) { -+ try { -+ this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.copiedBuffer(data)).readUtf(256); -+ } catch (StringIndexOutOfBoundsException ex) { -+ this.player.clientBrandName = "illegal"; ++ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); ++ ++ final net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id(); ++ final byte[] data = discardedPayload.data(); ++ try { ++ final boolean registerChannel = ServerCommonPacketListenerImpl.CUSTOM_REGISTER.equals(identifier); ++ if (registerChannel || ServerCommonPacketListenerImpl.CUSTOM_UNREGISTER.equals(identifier)) { ++ // Strings separated by zeros instead of length prefixes ++ int startIndex = 0; ++ for (int i = 0; i < data.length; i++) { ++ final byte b = data[i]; ++ if (b != 0) { ++ continue; + } ++ ++ readChannelIdentifier(data, startIndex, i, registerChannel); ++ startIndex = i + 1; + } -+ // Paper end - Brand support -+ this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data); -+ } catch (Exception ex) { -+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't dispatch custom payload", ex); -+ this.disconnect(Component.literal("Invalid custom payload!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause ++ ++ // Read the last one ++ readChannelIdentifier(data, startIndex, data.length, registerChannel); ++ return; + } ++ ++ if (identifier.equals(MINECRAFT_BRAND)) { ++ this.player.clientBrandName = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.wrappedBuffer(data)).readUtf(256); ++ } ++ ++ this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data); ++ } catch (final Exception e) { ++ ServerGamePacketListenerImpl.LOGGER.error("Couldn't handle custom payload on channel {}", identifier, e); ++ this.disconnect(Component.literal("Invalid custom payload payload!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause ++ } ++ } ++ ++ private void readChannelIdentifier(final byte[] data, final int from, final int to, final boolean register) { ++ final int length = to - from; ++ if (length == 0) { ++ return; ++ } ++ ++ final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII); ++ if (register) { ++ this.getCraftPlayer().addChannel(channel); ++ } else { ++ this.getCraftPlayer().removeChannel(channel); + } + } + + public final boolean isDisconnected() { + return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs + } -+ // CraftBukkit end ++ // Paper end @Override public void handleResourcePackResponse(ServerboundResourcePackPacket packet) { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/HorseInventoryMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/HorseInventoryMenu.java.patch index 8128aca0d..5f7e1b774 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/HorseInventoryMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/HorseInventoryMenu.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/inventory/HorseInventoryMenu.java +++ b/net/minecraft/world/inventory/HorseInventoryMenu.java @@ -19,9 +_,23 @@ - private final AbstractHorse horse; + public final AbstractHorse horse; public static final int SLOT_BODY_ARMOR = 1; private static final int SLOT_HORSE_INVENTORY_START = 2; + // CraftBukkit start 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 5050f446e..cc4b2061a 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 @@ -6,7 +6,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.io.BaseEncoding; import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Pair; -import io.netty.buffer.Unpooled; import io.papermc.paper.FeatureHooks; import io.papermc.paper.configuration.GlobalConfiguration; import io.papermc.paper.entity.LookAnchor; @@ -103,7 +102,6 @@ import net.minecraft.server.players.UserWhiteListEntry; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.attributes.AttributeInstance; -import net.minecraft.world.entity.ai.attributes.AttributeMap; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.food.FoodData; @@ -174,7 +172,6 @@ import org.bukkit.craftbukkit.map.CraftMapView; import org.bukkit.craftbukkit.map.RenderData; import org.bukkit.craftbukkit.potion.CraftPotionEffectType; import org.bukkit.craftbukkit.potion.CraftPotionUtil; -import org.bukkit.craftbukkit.profile.CraftPlayerProfile; import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; import org.bukkit.craftbukkit.util.CraftChatMessage; import org.bukkit.craftbukkit.util.CraftLocation; @@ -189,7 +186,6 @@ import org.bukkit.event.player.PlayerExpCooldownChangeEvent; import org.bukkit.event.player.PlayerHideEntityEvent; import org.bukkit.event.player.PlayerRegisterChannelEvent; import org.bukkit.event.player.PlayerShowEntityEvent; -import org.bukkit.event.player.PlayerSpawnChangeEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerUnregisterChannelEvent; import org.bukkit.inventory.EquipmentSlot; @@ -202,7 +198,6 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.messaging.StandardMessenger; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.bukkit.profile.PlayerProfile; import org.bukkit.scoreboard.Scoreboard; import org.jetbrains.annotations.NotNull; @@ -2463,7 +2458,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } private void sendCustomPayload(ResourceLocation id, byte[] message) { - ClientboundCustomPayloadPacket packet = new ClientboundCustomPayloadPacket(new DiscardedPayload(id, Unpooled.wrappedBuffer(message))); + ClientboundCustomPayloadPacket packet = new ClientboundCustomPayloadPacket(new DiscardedPayload(id, message)); this.getHandle().connection.send(packet); }