diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch index 38d73de462..1cf8d3c76b 100644 --- a/patches/api/Adventure.patch +++ b/patches/api/Adventure.patch @@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 withJavadocJar() } -+val adventureVersion = "4.8.1" ++val adventureVersion = "4.9.1" +val apiAndDocs by configurations.creating { + attributes { + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) @@ -1696,6 +1696,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Deprecated // Paper public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException; + /** +@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * + * @param title Title text + * @param subtitle Subtitle text +- * @deprecated API behavior subject to change ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ + @Deprecated + public void sendTitle(@Nullable String title, @Nullable String subtitle); +@@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * @param fadeIn time in ticks for titles to fade in. Defaults to 10. + * @param stay time in ticks for titles to stay. Defaults to 70. + * @param fadeOut time in ticks for titles to fade out. Defaults to 20. ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ ++ @Deprecated // Paper - Adventure + public void sendTitle(@Nullable String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut); + /** @@ -0,0 +0,0 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM */ @@ -3571,6 +3590,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public @NotNull MapCursor addCursor(int x, int y, byte direction, byte type, boolean visible, @Nullable net.kyori.adventure.text.Component caption) { + return addCursor(new MapCursor((byte) x, (byte) y, direction, type, visible, caption)); + } ++ // Paper end + } +diff --git a/src/main/java/org/bukkit/permissions/Permissible.java b/src/main/java/org/bukkit/permissions/Permissible.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/permissions/Permissible.java ++++ b/src/main/java/org/bukkit/permissions/Permissible.java +@@ -0,0 +0,0 @@ public interface Permissible extends ServerOperator { + */ + @NotNull + public Set getEffectivePermissions(); ++ ++ // Paper start - add TriState permission checks ++ /** ++ * Checks if this object has a permission set and, if it is set, the value of the permission. ++ * ++ * @param permission the permission to check ++ * @return a tri-state of if the permission is set and, if it is set, it's value ++ */ ++ default net.kyori.adventure.util.@NotNull TriState permissionValue(final @NotNull Permission permission) { ++ if (this.isPermissionSet(permission)) { ++ return net.kyori.adventure.util.TriState.byBoolean(this.hasPermission(permission)); ++ } else { ++ return net.kyori.adventure.util.TriState.NOT_SET; ++ } ++ } ++ ++ /** ++ * Checks if this object has a permission set and, if it is set, the value of the permission. ++ * ++ * @param permission the permission to check ++ * @return a tri-state of if the permission is set and, if it is set, it's value ++ */ ++ default net.kyori.adventure.util.@NotNull TriState permissionValue(final @NotNull String permission) { ++ if (this.isPermissionSet(permission)) { ++ return net.kyori.adventure.util.TriState.byBoolean(this.hasPermission(permission)); ++ } else { ++ return net.kyori.adventure.util.TriState.NOT_SET; ++ } ++ } + // Paper end } diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java diff --git a/patches/api/Build-system-changes.patch b/patches/api/Build-system-changes.patch index a3b571a649..1f81d1cffe 100644 --- a/patches/api/Build-system-changes.patch +++ b/patches/api/Build-system-changes.patch @@ -24,6 +24,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 compileOnly(annotations) testCompileOnly(annotations) ++ // Paper start - add checker ++ val checkerAnnotations = "org.checkerframework:checker-qual:3.18.0" ++ compileOnlyApi(checkerAnnotations) ++ testCompileOnly(checkerAnnotations) ++ // Paper end ++ + testImplementation("junit:junit:4.13.1") + testImplementation("org.hamcrest:hamcrest-library:1.3") + testImplementation("org.ow2.asm:asm-tree:9.2") @@ -0,0 +0,0 @@ tasks.withType().configureEach { (options as StandardJavadocDocletOptions).links( "https://guava.dev/releases/21.0/api/docs/", diff --git a/patches/api/Player-Tab-List-and-Title-APIs.patch b/patches/api/Player-Tab-List-and-Title-APIs.patch index 7d7d129e72..46f121705b 100644 --- a/patches/api/Player-Tab-List-and-Title-APIs.patch +++ b/patches/api/Player-Tab-List-and-Title-APIs.patch @@ -474,7 +474,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ + @Deprecated + public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks); @@ -483,7 +483,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * Update the subtitle of titles displayed to the player + * + * @param subtitle Subtitle to set -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ + @Deprecated + public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent[] subtitle); @@ -492,7 +492,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * Update the subtitle of titles displayed to the player + * + * @param subtitle Subtitle to set -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ + @Deprecated + public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent subtitle); @@ -501,7 +501,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * Show the given title to the player, along with the last subtitle set, using the last set times + * + * @param title Title to set -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @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); @@ -510,7 +510,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * Show the given title to the player, along with the last subtitle set, using the last set times + * + * @param title Title to set -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @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); @@ -523,7 +523,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @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); @@ -536,7 +536,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @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); @@ -548,7 +548,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @param title the title to send + * @throws NullPointerException if the title is null -+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ + @Deprecated + void sendTitle(@NotNull Title title); @@ -560,7 +560,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + * + * @param title the title to send + * @throws NullPointerException if title is null -+ * @deprecated use {@link #showTitle(net.kyori.adventure.title.Title)} ++ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)} + */ + @Deprecated + void updateTitle(@NotNull Title title); diff --git a/patches/server/Adventure.patch b/patches/server/Adventure.patch index de3c95454c..ecbea39de8 100644 --- a/patches/server/Adventure.patch +++ b/patches/server/Adventure.patch @@ -1854,6 +1854,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } // Paper end } +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World { + private int waterAnimalSpawn = -1; + private int waterAmbientSpawn = -1; + private int ambientSpawn = -1; ++ private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers + + private static final Random rand = new Random(); + +@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World { + return this.spigot; + } + // Spigot end ++ ++ // Paper start - implement pointers ++ @Override ++ public net.kyori.adventure.pointer.Pointers pointers() { ++ if (this.adventure$pointers == null) { ++ this.adventure$pointers = net.kyori.adventure.pointer.Pointers.builder() ++ .withDynamic(net.kyori.adventure.identity.Identity.NAME, this::getName) ++ .withDynamic(net.kyori.adventure.identity.Identity.UUID, this::getUID) ++ .build(); ++ } ++ ++ return this.adventure$pointers; ++ } ++ // Paper end + } diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java @@ -2144,6 +2175,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 @Override public boolean isPermissionSet(String name) { return this.getCaller().isPermissionSet(name); +diff --git a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java ++++ b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java +@@ -0,0 +0,0 @@ import org.bukkit.plugin.Plugin; + public abstract class ServerCommandSender implements CommandSender { + private static PermissibleBase blockPermInst; + private final PermissibleBase perm; ++ private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers + + public ServerCommandSender() { + if (this instanceof CraftBlockCommandSender) { +@@ -0,0 +0,0 @@ public abstract class ServerCommandSender implements CommandSender { + return this.spigot; + } + // Spigot end ++ ++ // Paper start - implement pointers ++ @Override ++ public net.kyori.adventure.pointer.Pointers pointers() { ++ if (this.adventure$pointers == null) { ++ this.adventure$pointers = net.kyori.adventure.pointer.Pointers.builder() ++ .withDynamic(net.kyori.adventure.identity.Identity.DISPLAY_NAME, this::name) ++ .withStatic(net.kyori.adventure.permission.PermissionChecker.POINTER, this::permissionValue) ++ .build(); ++ } ++ ++ return this.adventure$pointers; ++ } ++ // Paper end + } diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java @@ -2165,6 +2227,14 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/ index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + protected Entity entity; + private EntityDamageEvent lastDamageEvent; + private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftEntity.DATA_TYPE_REGISTRY); ++ protected net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers + + public CraftEntity(final CraftServer server, final Entity entity) { + this.server = server; @@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return this.getHandle().getVehicle().getBukkitEntity(); } @@ -2180,6 +2250,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public void customName(final net.kyori.adventure.text.Component customName) { + this.getHandle().setCustomName(customName != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(customName) : null); + } ++ ++ @Override ++ public net.kyori.adventure.pointer.Pointers pointers() { ++ if (this.adventure$pointers == null) { ++ this.adventure$pointers = net.kyori.adventure.pointer.Pointers.builder() ++ .withDynamic(net.kyori.adventure.identity.Identity.DISPLAY_NAME, this::name) ++ .withDynamic(net.kyori.adventure.identity.Identity.UUID, this::getUniqueId) ++ .withStatic(net.kyori.adventure.permission.PermissionChecker.POINTER, this::permissionValue) ++ .build(); ++ } ++ ++ return this.adventure$pointers; ++ } + // Paper end + @Override @@ -2508,6 +2591,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + connection.send(tp); + } + ++ @Override ++ public void sendTitlePart(final net.kyori.adventure.title.TitlePart part, T value) { ++ java.util.Objects.requireNonNull(part, "part"); ++ java.util.Objects.requireNonNull(value, "value"); ++ if (part == net.kyori.adventure.title.TitlePart.TITLE) { ++ final ClientboundSetTitleTextPacket tp = new ClientboundSetTitleTextPacket((net.minecraft.network.chat.Component) null); ++ tp.adventure$text = (net.kyori.adventure.text.Component) value; ++ this.getHandle().connection.send(tp); ++ } else if (part == net.kyori.adventure.title.TitlePart.SUBTITLE) { ++ final ClientboundSetSubtitleTextPacket sp = new ClientboundSetSubtitleTextPacket((net.minecraft.network.chat.Component) null); ++ sp.adventure$text = (net.kyori.adventure.text.Component) value; ++ this.getHandle().connection.send(sp); ++ } else if (part == net.kyori.adventure.title.TitlePart.TIMES) { ++ final net.kyori.adventure.title.Title.Times times = (net.kyori.adventure.title.Title.Times) value; ++ this.getHandle().connection.send(new ClientboundSetTitlesAnimationPacket(ticks(times.fadeIn()), ticks(times.stay()), ticks(times.fadeOut()))); ++ } else { ++ throw new IllegalArgumentException("Unknown TitlePart"); ++ } ++ } ++ + private static int ticks(final java.time.Duration duration) { + if (duration == null) { + return -1; @@ -2590,6 +2693,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + connection.send(new net.minecraft.network.protocol.game.ClientboundOpenBookPacket(net.minecraft.world.InteractionHand.MAIN_HAND)); + connection.send(new net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket(0, stateId, slot, inventory.getSelected())); + } ++ ++ @Override ++ public net.kyori.adventure.pointer.Pointers pointers() { ++ if (this.adventure$pointers == null) { ++ this.adventure$pointers = net.kyori.adventure.pointer.Pointers.builder() ++ .withDynamic(net.kyori.adventure.identity.Identity.DISPLAY_NAME, this::displayName) ++ .withDynamic(net.kyori.adventure.identity.Identity.NAME, this::getName) ++ .withDynamic(net.kyori.adventure.identity.Identity.UUID, this::getUniqueId) ++ .withStatic(net.kyori.adventure.permission.PermissionChecker.POINTER, this::permissionValue) ++ .withDynamic(net.kyori.adventure.identity.Identity.LOCALE, this::locale) ++ .build(); ++ } ++ ++ return this.adventure$pointers; ++ } + // Paper end + // Spigot start diff --git a/patches/server/Expose-attack-cooldown-methods-for-Player.patch b/patches/server/Expose-attack-cooldown-methods-for-Player.patch index 24b2e7f6f8..1dee849592 100644 --- a/patches/server/Expose-attack-cooldown-methods-for-Player.patch +++ b/patches/server/Expose-attack-cooldown-methods-for-Player.patch @@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player { - connection.send(new net.minecraft.network.protocol.game.ClientboundOpenBookPacket(net.minecraft.world.InteractionHand.MAIN_HAND)); - connection.send(new net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket(0, stateId, slot, inventory.getSelected())); + + return this.adventure$pointers; } + + @Override diff --git a/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch b/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch index 131510c186..ff9d72ee63 100644 --- a/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch +++ b/patches/server/Provide-E-TE-Chunk-count-stat-methods.patch @@ -24,8 +24,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World { - private int waterAmbientSpawn = -1; private int ambientSpawn = -1; + private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers + // Paper start - Provide fast information methods + @Override