Paper/patches/api/0006-Adventure.patch
Jake Potrebic 0ae58c09a1
cleanup player death event adventure logic (#10095)
There was a TODO left there regarding the translated death
message being used by plugins to identify the cause of death. This
should be mitigated now because the LegacyComponentSerializer default
implemenation uses our custom flattener which renders vanilla
translatable components to their English representation.
2023-12-29 12:28:58 -08:00

5208 lines
217 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Riley Park <rileysebastianpark@gmail.com>
Date: Fri, 29 Jan 2021 17:21:55 +0100
Subject: [PATCH] Adventure
Co-authored-by: zml <zml@stellardrift.ca>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
diff --git a/build.gradle.kts b/build.gradle.kts
index cc8f297a71eb75b3388ff1cb21a297e268894aac..4f5ac0c5fe6494d5fe5caa8ed5077a83cf43fa87 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -11,12 +11,28 @@ java {
val annotationsVersion = "24.0.1"
val bungeeCordChatVersion = "1.20-R0.1"
+val adventureVersion = "4.15.0"
+val apiAndDocs: Configuration by configurations.creating {
+ attributes {
+ attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
+ attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
+ attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType.SOURCES))
+ attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
+ }
+}
+configurations.api {
+ extendsFrom(apiAndDocs)
+}
dependencies {
// api dependencies are listed transitively to API consumers
api("com.google.guava:guava:32.1.2-jre")
api("com.google.code.gson:gson:2.10.1")
- api("net.md-5:bungeecord-chat:$bungeeCordChatVersion")
+ // Paper start - adventure
+ api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.14") {
+ exclude("com.google.guava", "guava")
+ }
+ // Paper - adventure
api("org.yaml:snakeyaml:2.2")
api("org.joml:joml:1.10.5")
// Paper start
@@ -24,6 +40,13 @@ dependencies {
isTransitive = false // includes junit
}
api("it.unimi.dsi:fastutil:8.5.6")
+ apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion"))
+ apiAndDocs("net.kyori:adventure-api")
+ apiAndDocs("net.kyori:adventure-text-minimessage")
+ apiAndDocs("net.kyori:adventure-text-serializer-gson")
+ apiAndDocs("net.kyori:adventure-text-serializer-legacy")
+ apiAndDocs("net.kyori:adventure-text-serializer-plain")
+ apiAndDocs("net.kyori:adventure-text-logger-slf4j")
// Paper end
compileOnly("org.apache.maven:maven-resolver-provider:3.9.6")
@@ -99,14 +122,30 @@ tasks.withType<Javadoc> {
"https://guava.dev/releases/32.1.2-jre/api/docs/",
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
"https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/", // Paper - we don't want Java 5 annotations
- "https://javadoc.io/doc/net.md-5/bungeecord-chat/$bungeeCordChatVersion/",
+ // "https://javadoc.io/doc/net.md-5/bungeecord-chat/$bungeeCordChatVersion/", // Paper - don't link to bungee chat
// Paper start - add missing javadoc links
"https://javadoc.io/doc/org.joml/joml/1.10.5/index.html",
"https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
// Paper end
+ // Paper start
+ "https://jd.advntr.dev/api/$adventureVersion/",
+ "https://jd.advntr.dev/text-minimessage/$adventureVersion/",
+ "https://jd.advntr.dev/text-serializer-gson/$adventureVersion/",
+ "https://jd.advntr.dev/text-serializer-legacy/$adventureVersion/",
+ "https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
+ "https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
+ // Paper end
)
options.tags("apiNote:a:API Note:")
+ inputs.files(apiAndDocs).ignoreEmptyDirectories().withPropertyName(apiAndDocs.name + "-configuration")
+ doFirst {
+ options.addStringOption(
+ "sourcepath",
+ apiAndDocs.resolvedConfiguration.files.joinToString(separator = File.pathSeparator, transform = File::getPath)
+ )
+ }
+
// workaround for https://github.com/gradle/gradle/issues/4046
inputs.dir("src/main/javadoc").withPropertyName("javadoc-sourceset")
doLast {
diff --git a/src/main/java/io/papermc/paper/chat/ChatRenderer.java b/src/main/java/io/papermc/paper/chat/ChatRenderer.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffe0a921cc1ebbb95104f22b57e0e3af85e287a6
--- /dev/null
+++ b/src/main/java/io/papermc/paper/chat/ChatRenderer.java
@@ -0,0 +1,71 @@
+package io.papermc.paper.chat;
+
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * A chat renderer is responsible for rendering chat messages sent by {@link Player}s to the server.
+ */
+@FunctionalInterface
+public interface ChatRenderer {
+ /**
+ * Renders a chat message. This will be called once for each receiving {@link Audience}.
+ *
+ * @param source the message source
+ * @param sourceDisplayName the display name of the source player
+ * @param message the chat message
+ * @param viewer the receiving {@link Audience}
+ * @return a rendered chat message
+ */
+ @ApiStatus.OverrideOnly
+ @NotNull
+ Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message, @NotNull Audience viewer);
+
+ /**
+ * Create a new instance of the default {@link ChatRenderer}.
+ *
+ * @return a new {@link ChatRenderer}
+ */
+ @NotNull
+ static ChatRenderer defaultRenderer() {
+ return new ViewerUnawareImpl.Default((source, sourceDisplayName, message) -> Component.translatable("chat.type.text", sourceDisplayName, message));
+ }
+
+ @ApiStatus.Internal
+ sealed interface Default extends ChatRenderer, ViewerUnaware permits ViewerUnawareImpl.Default {
+ }
+
+ /**
+ * Creates a new viewer-unaware {@link ChatRenderer}, which will render the chat message a single time,
+ * displaying the same rendered message to every viewing {@link Audience}.
+ *
+ * @param renderer the viewer unaware renderer
+ * @return a new {@link ChatRenderer}
+ */
+ @NotNull
+ static ChatRenderer viewerUnaware(final @NotNull ViewerUnaware renderer) {
+ return new ViewerUnawareImpl(renderer);
+ }
+
+ /**
+ * Similar to {@link ChatRenderer}, but without knowledge of the message viewer.
+ *
+ * @see ChatRenderer#viewerUnaware(ViewerUnaware)
+ */
+ interface ViewerUnaware {
+ /**
+ * Renders a chat message.
+ *
+ * @param source the message source
+ * @param sourceDisplayName the display name of the source player
+ * @param message the chat message
+ * @return a rendered chat message
+ */
+ @ApiStatus.OverrideOnly
+ @NotNull
+ Component render(@NotNull Player source, @NotNull Component sourceDisplayName, @NotNull Component message);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java b/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ad76b1751ba707f7ae0d283aa1cbaf6c9619da9
--- /dev/null
+++ b/src/main/java/io/papermc/paper/chat/ViewerUnawareImpl.java
@@ -0,0 +1,35 @@
+package io.papermc.paper.chat;
+
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+sealed class ViewerUnawareImpl implements ChatRenderer, ChatRenderer.ViewerUnaware permits ViewerUnawareImpl.Default {
+ private final ViewerUnaware unaware;
+ private @Nullable Component message;
+
+ ViewerUnawareImpl(final ViewerUnaware unaware) {
+ this.unaware = unaware;
+ }
+
+ @Override
+ public @NotNull Component render(final @NotNull Player source, final @NotNull Component sourceDisplayName, final @NotNull Component message, final @NotNull Audience viewer) {
+ return this.render(source, sourceDisplayName, message);
+ }
+
+ @Override
+ public @NotNull Component render(final @NotNull Player source, final @NotNull Component sourceDisplayName, final @NotNull Component message) {
+ if (this.message == null) {
+ this.message = this.unaware.render(source, sourceDisplayName, message);
+ }
+ return this.message;
+ }
+
+ static final class Default extends ViewerUnawareImpl implements ChatRenderer.Default {
+ Default(final ViewerUnaware unaware) {
+ super(unaware);
+ }
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AbstractChatEvent.java b/src/main/java/io/papermc/paper/event/player/AbstractChatEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed8e885f226b02b9875b23ae2294a9056d2e8b29
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AbstractChatEvent.java
@@ -0,0 +1,125 @@
+package io.papermc.paper.event.player;
+
+import io.papermc.paper.chat.ChatRenderer;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.chat.SignedMessage;
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * An abstract implementation of a chat event, handling shared logic.
+ */
+@ApiStatus.NonExtendable
+public abstract class AbstractChatEvent extends PlayerEvent implements Cancellable {
+ private final Set<Audience> viewers;
+ private final Component originalMessage;
+ private final SignedMessage signedMessage;
+ private ChatRenderer renderer;
+ private Component message;
+ private boolean cancelled = false;
+
+ AbstractChatEvent(final boolean async, final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
+ super(player, async);
+ this.viewers = viewers;
+ this.renderer = renderer;
+ this.message = message;
+ this.originalMessage = originalMessage;
+ this.signedMessage = signedMessage;
+ }
+
+ /**
+ * Gets a set of {@link Audience audiences} that this chat message will be displayed to.
+ *
+ * <p>The set returned may auto-populate on access. Any listener accessing the returned set should be aware that
+ * it may reduce performance for a lazy set implementation.</p>
+ *
+ * @return a mutable set of {@link Audience audiences} who will receive the chat message
+ */
+ @NotNull
+ public final Set<Audience> viewers() {
+ return this.viewers;
+ }
+
+ /**
+ * Sets the chat renderer.
+ *
+ * @param renderer the chat renderer
+ * @throws NullPointerException if {@code renderer} is {@code null}
+ */
+ public final void renderer(final @NotNull ChatRenderer renderer) {
+ this.renderer = requireNonNull(renderer, "renderer");
+ }
+
+ /**
+ * Gets the chat renderer.
+ *
+ * @return the chat renderer
+ */
+ @NotNull
+ public final ChatRenderer renderer() {
+ return this.renderer;
+ }
+
+ /**
+ * Gets the user-supplied message.
+ * The return value will reflect changes made using {@link #message(Component)}.
+ *
+ * @return the user-supplied message
+ */
+ @NotNull
+ public final Component message() {
+ return this.message;
+ }
+
+ /**
+ * Sets the user-supplied message.
+ *
+ * @param message the user-supplied message
+ * @throws NullPointerException if {@code message} is {@code null}
+ */
+ public final void message(final @NotNull Component message) {
+ this.message = requireNonNull(message, "message");
+ }
+
+ /**
+ * Gets the original and unmodified user-supplied message.
+ * The return value will <b>not</b> reflect changes made using
+ * {@link #message(Component)}.
+ *
+ * @return the original user-supplied message
+ */
+ @NotNull
+ public final Component originalMessage() {
+ return this.originalMessage;
+ }
+
+ /**
+ * Gets the signed message.
+ * Changes made in this event will <b>not</b> update
+ * the signed message.
+ *
+ * @return the signed message
+ */
+ @NotNull
+ public final SignedMessage signedMessage() {
+ return this.signedMessage;
+ }
+
+ @Override
+ public final boolean isCancelled() {
+ return this.cancelled;
+ }
+
+ @Override
+ public final void setCancelled(final boolean cancelled) {
+ this.cancelled = cancelled;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AsyncChatCommandDecorateEvent.java b/src/main/java/io/papermc/paper/event/player/AsyncChatCommandDecorateEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..feece00981ebf932e64760e7a10a04ad080d0228
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AsyncChatCommandDecorateEvent.java
@@ -0,0 +1,28 @@
+package io.papermc.paper.event.player;
+
+import net.kyori.adventure.text.Component;
+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;
+
+@ApiStatus.Experimental
+public class AsyncChatCommandDecorateEvent extends AsyncChatDecorateEvent {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ @ApiStatus.Internal
+ public AsyncChatCommandDecorateEvent(boolean async, @Nullable Player player, @NotNull Component originalMessage, @NotNull Component result) {
+ super(async, player, originalMessage, result);
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static @NotNull HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AsyncChatDecorateEvent.java b/src/main/java/io/papermc/paper/event/player/AsyncChatDecorateEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..667bfa6afc35f8a8f475431171ee474af4e10afd
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AsyncChatDecorateEvent.java
@@ -0,0 +1,117 @@
+package io.papermc.paper.event.player;
+
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.server.ServerEvent;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * This event is fired when the server decorates a component for chat purposes. This is called
+ * before {@link AsyncChatEvent} and the other chat events. It is recommended that you modify the
+ * message here, and use the chat events for modifying receivers and later the chat type. If you
+ * want to keep the message as "signed" for the clients who get it, be sure to include the entire
+ * original message somewhere in the final message.
+ * @see AsyncChatCommandDecorateEvent for the decoration of messages sent via commands
+ */
+@ApiStatus.Experimental
+public class AsyncChatDecorateEvent extends ServerEvent implements Cancellable {
+
+ private static final HandlerList HANDLER_LIST = new HandlerList();
+
+ private final Player player;
+ private final Component originalMessage;
+ private Component result;
+ private boolean cancelled;
+
+ @ApiStatus.Internal
+ public AsyncChatDecorateEvent(final boolean async, final @Nullable Player player, final @NotNull Component originalMessage, final @NotNull Component result) {
+ super(async);
+ this.player = player;
+ this.originalMessage = originalMessage;
+ this.result = result;
+ }
+
+ /**
+ * Gets the player (if available) associated with this event.
+ * <p>
+ * Certain commands request decorations without a player context
+ * which is why this is possibly null.
+ *
+ * @return the player or null
+ */
+ public @Nullable Player player() {
+ return this.player;
+ }
+
+ /**
+ * Gets the original decoration input
+ *
+ * @return the input
+ */
+ public @NotNull Component originalMessage() {
+ return this.originalMessage;
+ }
+
+ /**
+ * Gets the decoration result. This may already be different from
+ * {@link #originalMessage()} if some other listener to this event
+ * <b>OR</b> the legacy preview event ({@link org.bukkit.event.player.AsyncPlayerChatPreviewEvent}
+ * changed the result.
+ *
+ * @return the result
+ */
+ public @NotNull Component result() {
+ return this.result;
+ }
+
+ /**
+ * Sets the resulting decorated component.
+ *
+ * @param result the result
+ */
+ public void result(@NotNull Component result) {
+ this.result = result;
+ }
+
+ /**
+ * If this decorating is part of a preview request/response.
+ *
+ * @return true if part of previewing
+ * @deprecated chat preview was removed in 1.19.3
+ */
+ @Deprecated(forRemoval = true)
+ @ApiStatus.ScheduledForRemoval(inVersion = "1.21")
+ @Contract(value = "-> false", pure = true)
+ public boolean isPreview() {
+ return false;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return this.cancelled;
+ }
+
+ /**
+ * A cancelled decorating event means that no changes to the result component
+ * will have any effect. The decorated component will be equal to the original
+ * component.
+ */
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return HANDLER_LIST;
+ }
+
+ public static @NotNull HandlerList getHandlerList() {
+ return HANDLER_LIST;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/AsyncChatEvent.java b/src/main/java/io/papermc/paper/event/player/AsyncChatEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..4d2eddba7dc88ba23b241ac7849114a30af968d3
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/AsyncChatEvent.java
@@ -0,0 +1,47 @@
+package io.papermc.paper.event.player;
+
+import java.util.Set;
+import io.papermc.paper.chat.ChatRenderer;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.chat.SignedMessage;
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * An event fired when a {@link Player} sends a chat message to the server.
+ * <p>
+ * This event will sometimes fire synchronously, depending on how it was
+ * triggered.
+ * <p>
+ * If a player is the direct cause of this event by an incoming packet, this
+ * event will be asynchronous. If a plugin triggers this event by compelling a
+ * player to chat, this event will be synchronous.
+ * <p>
+ * Care should be taken to check {@link #isAsynchronous()} and treat the event
+ * appropriately.
+ */
+public final class AsyncChatEvent extends AbstractChatEvent {
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ /**
+ * @param viewers A mutable set of viewers
+ */
+ @ApiStatus.Internal
+ public AsyncChatEvent(final boolean async, final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
+ super(async, player, viewers, renderer, message, originalMessage, signedMessage);
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/event/player/ChatEvent.java b/src/main/java/io/papermc/paper/event/player/ChatEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..af025704e978dc0b11be277ab4646da77eb3a60b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/event/player/ChatEvent.java
@@ -0,0 +1,42 @@
+package io.papermc.paper.event.player;
+
+import java.util.Set;
+import io.papermc.paper.chat.ChatRenderer;
+import net.kyori.adventure.audience.Audience;
+import net.kyori.adventure.chat.SignedMessage;
+import net.kyori.adventure.text.Component;
+import org.bukkit.Warning;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * An event fired when a {@link Player} sends a chat message to the server.
+ *
+ * @deprecated Listening to this event forces chat to wait for the main thread, delaying chat messages. It is recommended to use {@link AsyncChatEvent} instead, wherever possible.
+ */
+@Deprecated
+@Warning(reason = "Listening to this event forces chat to wait for the main thread, delaying chat messages.")
+public final class ChatEvent extends AbstractChatEvent {
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ /**
+ * @param viewers A mutable set of viewers
+ */
+ @ApiStatus.Internal
+ public ChatEvent(final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
+ super(false, player, viewers, renderer, message, originalMessage, signedMessage);
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+}
diff --git a/src/main/java/io/papermc/paper/text/PaperComponents.java b/src/main/java/io/papermc/paper/text/PaperComponents.java
new file mode 100644
index 0000000000000000000000000000000000000000..6e94562d79206d88b74b53814f9423f12a2e6e06
--- /dev/null
+++ b/src/main/java/io/papermc/paper/text/PaperComponents.java
@@ -0,0 +1,177 @@
+package io.papermc.paper.text;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.flattener.ComponentFlattener;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Entity;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+
+/**
+ * Paper API-specific methods for working with {@link Component}s and related.
+ */
+public final class PaperComponents {
+ private PaperComponents() {
+ throw new RuntimeException("PaperComponents is not to be instantiated!");
+ }
+
+ /**
+ * Resolves a component with a specific command sender and subject.
+ * <p>
+ * Note that in Vanilla, elevated permissions are usually required to use
+ * '@' selectors in various component types, but this method should not
+ * check such permissions from the sender.
+ * <p>
+ * A {@link CommandSender} argument is required to resolve:
+ * <ul>
+ * <li>{@link net.kyori.adventure.text.NBTComponent}</li>
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
+ * <li>{@link net.kyori.adventure.text.SelectorComponent}</li>
+ * </ul>
+ * A {@link Entity} argument is optional to help resolve:
+ * <ul>
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
+ * </ul>
+ * {@link net.kyori.adventure.text.TranslatableComponent}s don't require any extra arguments.
+ *
+ * @param input the component to resolve
+ * @param context the command sender to resolve with
+ * @param scoreboardSubject the scoreboard subject to use (for use with {@link net.kyori.adventure.text.ScoreComponent}s)
+ * @return the resolved component
+ * @throws IOException if a syntax error tripped during resolving
+ */
+ public static @NotNull Component resolveWithContext(@NotNull Component input, @Nullable CommandSender context, @Nullable Entity scoreboardSubject) throws IOException {
+ return resolveWithContext(input, context, scoreboardSubject, true);
+ }
+
+ /**
+ * Resolves a component with a specific command sender and subject.
+ * <p>
+ * Note that in Vanilla, elevated permissions are required to use
+ * '@' selectors in various component types. If the boolean {@code bypassPermissions}
+ * argument is {@code false}, the {@link CommandSender} argument will be used to query
+ * those permissions.
+ * <p>
+ * A {@link CommandSender} argument is required to resolve:
+ * <ul>
+ * <li>{@link net.kyori.adventure.text.NBTComponent}</li>
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
+ * <li>{@link net.kyori.adventure.text.SelectorComponent}</li>
+ * </ul>
+ * A {@link Entity} argument is optional to help resolve:
+ * <ul>
+ * <li>{@link net.kyori.adventure.text.ScoreComponent}</li>
+ * </ul>
+ * {@link net.kyori.adventure.text.TranslatableComponent}s don't require any extra arguments.
+ *
+ * @param input the component to resolve
+ * @param context the command sender to resolve with
+ * @param scoreboardSubject the scoreboard subject to use (for use with {@link net.kyori.adventure.text.ScoreComponent}s)
+ * @param bypassPermissions true to bypass permissions checks for resolving components
+ * @return the resolved component
+ * @throws IOException if a syntax error tripped during resolving
+ */
+ public static @NotNull Component resolveWithContext(@NotNull Component input, @Nullable CommandSender context, @Nullable Entity scoreboardSubject, boolean bypassPermissions) throws IOException {
+ return Bukkit.getUnsafe().resolveWithContext(input, context, scoreboardSubject, bypassPermissions);
+ }
+
+ /**
+ * Return a component flattener that can use game data to resolve extra information about components.
+ *
+ * @return a component flattener
+ */
+ public static @NotNull ComponentFlattener flattener() {
+ return Bukkit.getUnsafe().componentFlattener();
+ }
+
+ /**
+ * Get a serializer for {@link Component}s that will convert components to
+ * a plain-text string.
+ *
+ * <p>Implementations may provide a serializer capable of processing any
+ * information that requires access to implementation details.</p>
+ *
+ * @return a serializer to plain text
+ * @deprecated will be removed in adventure 5.0.0, use {@link PlainTextComponentSerializer#plainText()}
+ */
+ @Deprecated(forRemoval = true)
+ public static @NotNull PlainComponentSerializer plainSerializer() {
+ return Bukkit.getUnsafe().plainComponentSerializer();
+ }
+
+ /**
+ * Get a serializer for {@link Component}s that will convert components to
+ * a plain-text string.
+ *
+ * <p>Implementations may provide a serializer capable of processing any
+ * information that requires access to implementation details.</p>
+ *
+ * @return a serializer to plain text
+ * @deprecated use {@link PlainTextComponentSerializer#plainText()}
+ */
+ @Deprecated(forRemoval = true)
+ public static @NotNull PlainTextComponentSerializer plainTextSerializer() {
+ return Bukkit.getUnsafe().plainTextSerializer();
+ }
+
+ /**
+ * Get a serializer for {@link Component}s that will convert to and from the
+ * standard JSON serialization format using Gson.
+ *
+ * <p>Implementations may provide a serializer capable of processing any
+ * information that requires implementation details, such as legacy
+ * (pre-1.16) hover events.</p>
+ *
+ * @return a json component serializer
+ * @deprecated use {@link GsonComponentSerializer#gson()}
+ */
+ @Deprecated(forRemoval = true)
+ public static @NotNull GsonComponentSerializer gsonSerializer() {
+ return Bukkit.getUnsafe().gsonComponentSerializer();
+ }
+
+ /**
+ * Get a serializer for {@link Component}s that will convert to and from the
+ * standard JSON serialization format using Gson, downsampling any RGB colors
+ * to their nearest {@link NamedTextColor} counterpart.
+ *
+ * <p>Implementations may provide a serializer capable of processing any
+ * information that requires implementation details, such as legacy
+ * (pre-1.16) hover events.</p>
+ *
+ * @return a json component serializer
+ * @deprecated use {@link GsonComponentSerializer#colorDownsamplingGson()}
+ */
+ @Deprecated(forRemoval = true)
+ public static @NotNull GsonComponentSerializer colorDownsamplingGsonSerializer() {
+ return Bukkit.getUnsafe().colorDownsamplingGsonComponentSerializer();
+ }
+
+ /**
+ * Get a serializer for {@link Component}s that will convert to and from the
+ * legacy component format used by Bukkit. This serializer uses the
+ * {@link LegacyComponentSerializer.Builder#useUnusualXRepeatedCharacterHexFormat()}
+ * option to match upstream behavior.
+ *
+ * <p>This legacy serializer uses the standard section symbol to mark
+ * formatting characters.</p>
+ *
+ * <p>Implementations may provide a serializer capable of processing any
+ * information that requires access to implementation details.</p>
+ *
+ * @return a section serializer
+ * @deprecated use {@link LegacyComponentSerializer#legacySection()}
+ */
+ @Deprecated(forRemoval = true)
+ public static @NotNull LegacyComponentSerializer legacySectionSerializer() {
+ return Bukkit.getUnsafe().legacyComponentSerializer();
+ }
+}
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 5680a77cc98cdb4b4c002d1366e775acaf747e51..a0fce496d2b90f484d2723c4ea4099ad29dc438f 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -400,7 +400,9 @@ public final class Bukkit {
*
* @param message the message
* @return the number of players
+ * @deprecated in favour of {@link Server#broadcast(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public static int broadcastMessage(@NotNull String message) {
return server.broadcastMessage(message);
}
@@ -1191,6 +1193,19 @@ public final class Bukkit {
server.shutdown();
}
+ // Paper start
+ /**
+ * Broadcast a message to all players.
+ * <p>
+ * This is the same as calling {@link #broadcast(net.kyori.adventure.text.Component,
+ * java.lang.String)} with the {@link Server#BROADCAST_CHANNEL_USERS} permission.
+ *
+ * @param message the message
+ * @return the number of players
+ */
+ public static int broadcast(net.kyori.adventure.text.@NotNull Component message) {
+ return server.broadcast(message);
+ }
/**
* Broadcasts the specified message to every user with the given
* permission name.
@@ -1200,6 +1215,21 @@ public final class Bukkit {
* permissibles} must have to receive the broadcast
* @return number of message recipients
*/
+ public static int broadcast(net.kyori.adventure.text.@NotNull Component message, @NotNull String permission) {
+ return server.broadcast(message, permission);
+ }
+ // Paper end
+ /**
+ * Broadcasts the specified message to every user with the given
+ * permission name.
+ *
+ * @param message message to broadcast
+ * @param permission the required permission {@link Permissible
+ * permissibles} must have to receive the broadcast
+ * @return number of message recipients
+ * @deprecated in favour of {@link #broadcast(net.kyori.adventure.text.Component, String)}
+ */
+ @Deprecated // Paper
public static int broadcast(@NotNull String message, @NotNull String permission) {
return server.broadcast(message, permission);
}
@@ -1461,6 +1491,7 @@ public final class Bukkit {
return server.createInventory(owner, type);
}
+ // Paper start
/**
* Creates an empty inventory with the specified type and title. If the type
* is {@link InventoryType#CHEST}, the new inventory has a size of 27;
@@ -1486,6 +1517,38 @@ public final class Bukkit {
* @see InventoryType#isCreatable()
*/
@NotNull
+ public static Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, net.kyori.adventure.text.@NotNull Component title) {
+ return server.createInventory(owner, type, title);
+ }
+ // Paper end
+
+ /**
+ * Creates an empty inventory with the specified type and title. If the type
+ * is {@link InventoryType#CHEST}, the new inventory has a size of 27;
+ * otherwise the new inventory has the normal size for its type.<br>
+ * It should be noted that some inventory types do not support titles and
+ * may not render with said titles on the Minecraft client.
+ * <br>
+ * {@link InventoryType#WORKBENCH} will not process crafting recipes if
+ * created with this method. Use
+ * {@link Player#openWorkbench(Location, boolean)} instead.
+ * <br>
+ * {@link InventoryType#ENCHANTING} will not process {@link ItemStack}s
+ * for possible enchanting results. Use
+ * {@link Player#openEnchanting(Location, boolean)} instead.
+ *
+ * @param owner The holder of the inventory; can be null if there's no holder.
+ * @param type The type of inventory to create.
+ * @param title The title of the inventory, to be displayed when it is viewed.
+ * @return The new inventory.
+ * @throws IllegalArgumentException if the {@link InventoryType} cannot be
+ * viewed.
+ * @deprecated in favour of {@link #createInventory(InventoryHolder, InventoryType, net.kyori.adventure.text.Component)}
+ *
+ * @see InventoryType#isCreatable()
+ */
+ @Deprecated // Paper
+ @NotNull
public static Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, @NotNull String title) {
return server.createInventory(owner, type, title);
}
@@ -1504,6 +1567,7 @@ public final class Bukkit {
return server.createInventory(owner, size);
}
+ // Paper start
/**
* Creates an empty inventory of type {@link InventoryType#CHEST} with the
* specified size and title.
@@ -1516,10 +1580,30 @@ public final class Bukkit {
* @throws IllegalArgumentException if the size is not a multiple of 9
*/
@NotNull
+ public static Inventory createInventory(@Nullable InventoryHolder owner, int size, net.kyori.adventure.text.@NotNull Component title) throws IllegalArgumentException {
+ return server.createInventory(owner, size, title);
+ }
+ // Paper end
+
+ /**
+ * Creates an empty inventory of type {@link InventoryType#CHEST} with the
+ * specified size and title.
+ *
+ * @param owner the holder of the inventory, or null to indicate no holder
+ * @param size a multiple of 9 as the size of inventory to create
+ * @param title the title of the inventory, displayed when inventory is
+ * viewed
+ * @return a new inventory
+ * @throws IllegalArgumentException if the size is not a multiple of 9
+ * @deprecated in favour of {@link #createInventory(InventoryHolder, InventoryType, net.kyori.adventure.text.Component)}
+ */
+ @Deprecated // Paper
+ @NotNull
public static Inventory createInventory(@Nullable InventoryHolder owner, int size, @NotNull String title) throws IllegalArgumentException {
return server.createInventory(owner, size, title);
}
+ // Paper start
/**
* Creates an empty merchant.
*
@@ -1527,7 +1611,20 @@ public final class Bukkit {
* when the merchant inventory is viewed
* @return a new merchant
*/
+ public static @NotNull Merchant createMerchant(net.kyori.adventure.text.@Nullable Component title) {
+ return server.createMerchant(title);
+ }
+ // Paper start
+ /**
+ * Creates an empty merchant.
+ *
+ * @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)}
+ */
@NotNull
+ @Deprecated // Paper
public static Merchant createMerchant(@Nullable String title) {
return server.createMerchant(title);
}
@@ -1644,12 +1741,43 @@ public final class Bukkit {
return server.isPrimaryThread();
}
+ // Paper start
+ /**
+ * Gets the message that is displayed on the server list.
+ *
+ * @return the server's MOTD
+ */
+ @NotNull public static net.kyori.adventure.text.Component motd() {
+ return server.motd();
+ }
+
+ /**
+ * Set the message that is displayed on the server list.
+ *
+ * @param motd The message to be displayed
+ */
+ public static void motd(final net.kyori.adventure.text.@NotNull Component motd) {
+ server.motd(motd);
+ }
+
+ /**
+ * Gets the default message that is displayed when the server is stopped.
+ *
+ * @return the shutdown message
+ */
+ public static net.kyori.adventure.text.@Nullable Component shutdownMessage() {
+ return server.shutdownMessage();
+ }
+ // Paper end
+
/**
* Gets the message that is displayed on the server list.
*
* @return the servers MOTD
+ * @deprecated in favour of {@link #motd()}
*/
@NotNull
+ @Deprecated // Paper
public static String getMotd() {
return server.getMotd();
}
@@ -1658,7 +1786,9 @@ public final class Bukkit {
* Set the message that is displayed on the server list.
*
* @param motd The message to be displayed
+ * @deprecated in favour of {@link #motd(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public static void setMotd(@NotNull String motd) {
server.setMotd(motd);
}
@@ -1667,8 +1797,10 @@ public final class Bukkit {
* Gets the default message that is displayed when the server is stopped.
*
* @return the shutdown message
+ * @deprecated in favour of {@link #shutdownMessage()}
*/
@Nullable
+ @Deprecated // Paper
public static String getShutdownMessage() {
return server.getShutdownMessage();
}
diff --git a/src/main/java/org/bukkit/ChatColor.java b/src/main/java/org/bukkit/ChatColor.java
index e3f185dc982d1c38195a4e01ddd485c13ffa58c0..918a045165cdcde264bc24082b7afebb407271de 100644
--- a/src/main/java/org/bukkit/ChatColor.java
+++ b/src/main/java/org/bukkit/ChatColor.java
@@ -10,7 +10,9 @@ import org.jetbrains.annotations.Nullable;
/**
* All supported color values for chat
+ * @deprecated ChatColor has been deprecated in favor of <a href="https://docs.advntr.dev/text.html">Adventure</a> API. See {@link net.kyori.adventure.text.format.NamedTextColor} for the adventure equivalent of pre-defined text colors
*/
+@Deprecated // Paper
public enum ChatColor {
/**
* Represents black
diff --git a/src/main/java/org/bukkit/Keyed.java b/src/main/java/org/bukkit/Keyed.java
index 32c92621c2c15eec14c50965f5ecda00c46e6c80..e076d447da62445764a9776ee2554c077637d270 100644
--- a/src/main/java/org/bukkit/Keyed.java
+++ b/src/main/java/org/bukkit/Keyed.java
@@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull;
/**
* Represents an object which has a {@link NamespacedKey} attached to it.
*/
-public interface Keyed {
+public interface Keyed extends net.kyori.adventure.key.Keyed { // Paper -- extend Adventure Keyed
/**
* Return the namespaced identifier for this object.
@@ -14,4 +14,16 @@ public interface Keyed {
*/
@NotNull
NamespacedKey getKey();
+
+ // Paper start
+ /**
+ * Returns the unique identifier for this object.
+ *
+ * @return this object's key
+ */
+ @Override
+ default net.kyori.adventure.key.@NotNull Key key() {
+ return this.getKey();
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/Nameable.java b/src/main/java/org/bukkit/Nameable.java
index b79daa857fc686f00ac06b8851e0ab68d83ae949..45d996878ba8d314a47078589b6da59dc84d589e 100644
--- a/src/main/java/org/bukkit/Nameable.java
+++ b/src/main/java/org/bukkit/Nameable.java
@@ -7,6 +7,30 @@ import org.jetbrains.annotations.Nullable;
*/
public interface Nameable {
+ // Paper start
+ /**
+ * Gets the custom name.
+ *
+ * <p>This value has no effect on players, they will always use their real name.</p>
+ *
+ * @return the custom name
+ */
+ net.kyori.adventure.text.@Nullable Component customName();
+
+ /**
+ * Sets the custom name.
+ *
+ * <p>This name will be used in death messages and can be sent to the client as a nameplate over the mob.</p>
+ *
+ * <p>Setting the name to {@code null} will clear it.</p>
+ *
+ * <p>This value has no effect on players, they will always use their real name.</p>
+ *
+ * @param customName the custom name to set
+ */
+ void customName(final net.kyori.adventure.text.@Nullable Component customName);
+ // Paper end
+
/**
* Gets the custom name on a mob or block. If there is no name this method
* will return null.
@@ -14,8 +38,10 @@ public interface Nameable {
* This value has no effect on players, they will always use their real
* name.
*
+ * @deprecated in favour of {@link #customName()}
* @return name of the mob/block or null
*/
+ @Deprecated // Paper
@Nullable
public String getCustomName();
@@ -28,7 +54,9 @@ public interface Nameable {
* This value has no effect on players, they will always use their real
* name.
*
+ * @deprecated in favour of {@link #customName(net.kyori.adventure.text.Component)}
* @param name the name to set
*/
+ @Deprecated // Paper
public void setCustomName(@Nullable String name);
}
diff --git a/src/main/java/org/bukkit/NamespacedKey.java b/src/main/java/org/bukkit/NamespacedKey.java
index ae7b51341fb66c41b8a7c4604fd273d876e311be..4034fcb9abc39b12f0de47c4b679f2ef82353c89 100644
--- a/src/main/java/org/bukkit/NamespacedKey.java
+++ b/src/main/java/org/bukkit/NamespacedKey.java
@@ -19,7 +19,7 @@ import org.jetbrains.annotations.Nullable;
* underscores, hyphens, and forward slashes.
*
*/
-public final class NamespacedKey {
+public final class NamespacedKey implements net.kyori.adventure.key.Key { // Paper - implement Key
/**
* The namespace representing all inbuilt keys.
@@ -130,10 +130,11 @@ public final class NamespacedKey {
@Override
public int hashCode() {
- int hash = 5;
- hash = 47 * hash + this.namespace.hashCode();
- hash = 47 * hash + this.key.hashCode();
- return hash;
+ // Paper start
+ int result = this.namespace.hashCode();
+ result = (31 * result) + this.key.hashCode();
+ return result;
+ // Paper end
}
@Override
@@ -141,11 +142,10 @@ public final class NamespacedKey {
if (obj == null) {
return false;
}
- if (getClass() != obj.getClass()) {
- return false;
- }
- final NamespacedKey other = (NamespacedKey) obj;
- return this.namespace.equals(other.namespace) && this.key.equals(other.key);
+ // Paper start
+ if (!(obj instanceof net.kyori.adventure.key.Key key)) return false;
+ return this.namespace.equals(key.namespace()) && this.key.equals(key.value());
+ // Paper end
}
@Override
@@ -247,4 +247,24 @@ public final class NamespacedKey {
public static NamespacedKey fromString(@NotNull String key) {
return fromString(key, null);
}
+
+ // Paper start
+ @NotNull
+ @Override
+ public String namespace() {
+ return this.getNamespace();
+ }
+
+ @NotNull
+ @Override
+ public String value() {
+ return this.getKey();
+ }
+
+ @NotNull
+ @Override
+ public String asString() {
+ return this.namespace + ':' + this.key;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index c394954cab8213bd1073356524cdd5705ef54d12..83ae1490f6c48d931541e13f76950fcdc62a5c01 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -62,13 +62,13 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a server implementation.
*/
-public interface Server extends PluginMessageRecipient {
+public interface Server extends PluginMessageRecipient, net.kyori.adventure.audience.ForwardingAudience { // Paper
/**
* Used for all administrative messages, such as an operator using a
* command.
* <p>
- * For use in {@link #broadcast(java.lang.String, java.lang.String)}.
+ * For use in {@link #broadcast(net.kyori.adventure.text.Component, java.lang.String)}.
*/
public static final String BROADCAST_CHANNEL_ADMINISTRATIVE = "bukkit.broadcast.admin";
@@ -76,7 +76,7 @@ public interface Server extends PluginMessageRecipient {
* Used for all announcement messages, such as informing users that a
* player has joined.
* <p>
- * For use in {@link #broadcast(java.lang.String, java.lang.String)}.
+ * For use in {@link #broadcast(net.kyori.adventure.text.Component, java.lang.String)}.
*/
public static final String BROADCAST_CHANNEL_USERS = "bukkit.broadcast.user";
@@ -337,7 +337,9 @@ public interface Server extends PluginMessageRecipient {
*
* @param message the message
* @return the number of players
+ * @deprecated use {@link #broadcast(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public int broadcastMessage(@NotNull String message);
/**
@@ -1023,8 +1025,33 @@ public interface Server extends PluginMessageRecipient {
* @param permission the required permission {@link Permissible
* permissibles} must have to receive the broadcast
* @return number of message recipients
+ * @deprecated in favour of {@link #broadcast(net.kyori.adventure.text.Component, String)}
*/
+ @Deprecated // Paper
public int broadcast(@NotNull String message, @NotNull String permission);
+ // Paper start
+ /**
+ * Broadcast a message to all players.
+ * <p>
+ * This is the same as calling {@link #broadcast(net.kyori.adventure.text.Component,
+ * java.lang.String)} with the {@link #BROADCAST_CHANNEL_USERS} permission.
+ *
+ * @param message the message
+ * @return the number of players
+ */
+ int broadcast(net.kyori.adventure.text.@NotNull Component message);
+
+ /**
+ * Broadcasts the specified message to every user with the given
+ * permission name.
+ *
+ * @param message message to broadcast
+ * @param permission the required permission {@link Permissible
+ * permissibles} must have to receive the broadcast
+ * @return number of message recipients
+ */
+ int broadcast(net.kyori.adventure.text.@NotNull Component message, @NotNull String permission);
+ // Paper end
/**
* Gets the player by the given name, regardless if they are offline or
@@ -1241,6 +1268,35 @@ public interface Server extends PluginMessageRecipient {
@NotNull
Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type);
+ // Paper start
+ /**
+ * Creates an empty inventory with the specified type and title. If the type
+ * is {@link InventoryType#CHEST}, the new inventory has a size of 27;
+ * otherwise the new inventory has the normal size for its type.<br>
+ * It should be noted that some inventory types do not support titles and
+ * may not render with said titles on the Minecraft client.
+ * <br>
+ * {@link InventoryType#WORKBENCH} will not process crafting recipes if
+ * created with this method. Use
+ * {@link Player#openWorkbench(Location, boolean)} instead.
+ * <br>
+ * {@link InventoryType#ENCHANTING} will not process {@link ItemStack}s
+ * for possible enchanting results. Use
+ * {@link Player#openEnchanting(Location, boolean)} instead.
+ *
+ * @param owner The holder of the inventory; can be null if there's no holder.
+ * @param type The type of inventory to create.
+ * @param title The title of the inventory, to be displayed when it is viewed.
+ * @return The new inventory.
+ * @throws IllegalArgumentException if the {@link InventoryType} cannot be
+ * viewed.
+ *
+ * @see InventoryType#isCreatable()
+ */
+ @NotNull
+ Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, net.kyori.adventure.text.@NotNull Component title);
+ // Paper end
+
/**
* Creates an empty inventory with the specified type and title. If the type
* is {@link InventoryType#CHEST}, the new inventory has a size of 27;
@@ -1262,9 +1318,11 @@ public interface Server extends PluginMessageRecipient {
* @return The new inventory.
* @throws IllegalArgumentException if the {@link InventoryType} cannot be
* viewed.
+ * @deprecated in favour of {@link #createInventory(InventoryHolder, InventoryType, net.kyori.adventure.text.Component)}
*
* @see InventoryType#isCreatable()
*/
+ @Deprecated // Paper
@NotNull
Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type, @NotNull String title);
@@ -1280,6 +1338,22 @@ public interface Server extends PluginMessageRecipient {
@NotNull
Inventory createInventory(@Nullable InventoryHolder owner, int size) throws IllegalArgumentException;
+ // Paper start
+ /**
+ * Creates an empty inventory of type {@link InventoryType#CHEST} with the
+ * specified size and title.
+ *
+ * @param owner the holder of the inventory, or null to indicate no holder
+ * @param size a multiple of 9 as the size of inventory to create
+ * @param title the title of the inventory, displayed when inventory is
+ * viewed
+ * @return a new inventory
+ * @throws IllegalArgumentException if the size is not a multiple of 9
+ */
+ @NotNull
+ Inventory createInventory(@Nullable InventoryHolder owner, int size, net.kyori.adventure.text.@NotNull Component title) throws IllegalArgumentException;
+ // Paper end
+
/**
* Creates an empty inventory of type {@link InventoryType#CHEST} with the
* specified size and title.
@@ -1290,18 +1364,32 @@ public interface Server extends PluginMessageRecipient {
* viewed
* @return a new inventory
* @throws IllegalArgumentException if the size is not a multiple of 9
+ * @deprecated in favour of {@link #createInventory(InventoryHolder, int, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
@NotNull
Inventory createInventory(@Nullable InventoryHolder owner, int size, @NotNull String title) throws IllegalArgumentException;
+ // Paper start
+ /**
+ * Creates an empty merchant.
+ *
+ * @param title the title of the corresponding merchant inventory, displayed
+ * when the merchant inventory is viewed
+ * @return a new merchant
+ */
+ @NotNull Merchant createMerchant(net.kyori.adventure.text.@Nullable Component title);
+ // Paper start
/**
* Creates an empty merchant.
*
* @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)}
*/
@NotNull
+ @Deprecated // Paper
Merchant createMerchant(@Nullable String title);
/**
@@ -1397,27 +1485,56 @@ public interface Server extends PluginMessageRecipient {
*/
boolean isPrimaryThread();
+ // Paper start
+ /**
+ * Gets the message that is displayed on the server list.
+ *
+ * @return the server's MOTD
+ */
+ net.kyori.adventure.text.@NotNull Component motd();
+
+ /**
+ * Set the message that is displayed on the server list.
+ *
+ * @param motd The message to be displayed
+ */
+ void motd(final net.kyori.adventure.text.@NotNull Component motd);
+
+ /**
+ * Gets the default message that is displayed when the server is stopped.
+ *
+ * @return the shutdown message
+ */
+ net.kyori.adventure.text.@Nullable Component shutdownMessage();
+ // Paper end
+
/**
* Gets the message that is displayed on the server list.
*
* @return the servers MOTD
+ * @deprecated in favour of {@link #motd()}
*/
@NotNull
+ @Deprecated // Paper
String getMotd();
/**
* Set the message that is displayed on the server list.
*
* @param motd The message to be displayed
+ * @deprecated in favour of {@link #motd(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setMotd(@NotNull String motd);
/**
* Gets the default message that is displayed when the server is stopped.
*
* @return the shutdown message
+ * @deprecated in favour of {@link #shutdownMessage()}
*/
@Nullable
+ @Deprecated // Paper
String getShutdownMessage();
/**
@@ -1799,7 +1916,9 @@ public interface Server extends PluginMessageRecipient {
* Sends the component to the player
*
* @param component the components to send
+ * @deprecated use {@link #broadcast(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -1808,7 +1927,9 @@ public interface Server extends PluginMessageRecipient {
* Sends an array of components as a single message to the player
*
* @param components the components to send
+ * @deprecated use {@link #broadcast(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
throw new UnsupportedOperationException("Not supported yet.");
}
diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java
index 9b1247cdf8a2fed812c46c55193d574aafc3bc94..72ea6ddd00eed73459d700d657929f83ba1ca7ee 100644
--- a/src/main/java/org/bukkit/Sound.java
+++ b/src/main/java/org/bukkit/Sound.java
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
* guarantee values will not be removed from this Enum. As such, you should not
* depend on the ordinal values of this class.
*/
-public enum Sound implements Keyed {
+public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Paper - implement Sound.Type
AMBIENT_BASALT_DELTAS_ADDITIONS("ambient.basalt_deltas.additions"),
AMBIENT_BASALT_DELTAS_LOOP("ambient.basalt_deltas.loop"),
@@ -1614,4 +1614,11 @@ public enum Sound implements Keyed {
public NamespacedKey getKey() {
return key;
}
+
+ // Paper start
+ @Override
+ public net.kyori.adventure.key.@NotNull Key key() {
+ return this.key;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/SoundCategory.java b/src/main/java/org/bukkit/SoundCategory.java
index ac5e263d737973af077e3406a84a84baca4370db..2d91924b7f5ef16a91d40cdc1bfc3d68e0fda38d 100644
--- a/src/main/java/org/bukkit/SoundCategory.java
+++ b/src/main/java/org/bukkit/SoundCategory.java
@@ -3,7 +3,7 @@ package org.bukkit;
/**
* An Enum of categories for sounds.
*/
-public enum SoundCategory {
+public enum SoundCategory implements net.kyori.adventure.sound.Sound.Source.Provider { // Paper - implement Sound.Source.Provider
MASTER,
MUSIC,
@@ -15,4 +15,22 @@ public enum SoundCategory {
PLAYERS,
AMBIENT,
VOICE;
+
+ // Paper start - implement Sound.Source.Provider
+ @Override
+ public net.kyori.adventure.sound.Sound.@org.jetbrains.annotations.NotNull Source soundSource() {
+ return switch (this) {
+ case MASTER -> net.kyori.adventure.sound.Sound.Source.MASTER;
+ case MUSIC -> net.kyori.adventure.sound.Sound.Source.MUSIC;
+ case RECORDS -> net.kyori.adventure.sound.Sound.Source.RECORD;
+ case WEATHER -> net.kyori.adventure.sound.Sound.Source.WEATHER;
+ case BLOCKS -> net.kyori.adventure.sound.Sound.Source.BLOCK;
+ case HOSTILE -> net.kyori.adventure.sound.Sound.Source.HOSTILE;
+ case NEUTRAL -> net.kyori.adventure.sound.Sound.Source.NEUTRAL;
+ case PLAYERS -> net.kyori.adventure.sound.Sound.Source.PLAYER;
+ case AMBIENT -> net.kyori.adventure.sound.Sound.Source.AMBIENT;
+ case VOICE -> net.kyori.adventure.sound.Sound.Source.VOICE;
+ };
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
index 4a9a82540e40685d2b837c76c431827a00cf4ba3..a3ee6f2f588bc9c87e49378359f450820b9af1b9 100644
--- a/src/main/java/org/bukkit/UnsafeValues.java
+++ b/src/main/java/org/bukkit/UnsafeValues.java
@@ -26,6 +26,15 @@ import org.jetbrains.annotations.Nullable;
*/
@Deprecated
public interface UnsafeValues {
+ // Paper start
+ net.kyori.adventure.text.flattener.ComponentFlattener componentFlattener();
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.plain.PlainComponentSerializer plainComponentSerializer();
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer plainTextSerializer();
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.gson.GsonComponentSerializer gsonComponentSerializer();
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.gson.GsonComponentSerializer colorDownsamplingGsonComponentSerializer();
+ @Deprecated(forRemoval = true) net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer legacyComponentSerializer();
+ net.kyori.adventure.text.Component resolveWithContext(net.kyori.adventure.text.Component component, org.bukkit.command.CommandSender context, org.bukkit.entity.Entity scoreboardSubject, boolean bypassPermissions) throws java.io.IOException;
+ // Paper end
Material toLegacy(Material material);
diff --git a/src/main/java/org/bukkit/Warning.java b/src/main/java/org/bukkit/Warning.java
index efb97712cc9dc7c1e12a59f5b94e4f2ad7c6b7d8..3024468af4c073324e536c1cb26beffb1e09f3f4 100644
--- a/src/main/java/org/bukkit/Warning.java
+++ b/src/main/java/org/bukkit/Warning.java
@@ -67,6 +67,7 @@ public @interface Warning {
* </ul>
*/
public boolean printFor(@Nullable Warning warning) {
+ if (Boolean.getBoolean("paper.alwaysPrintWarningState")) return true; // Paper
if (this == DEFAULT) {
return warning == null || warning.value();
}
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index 6e7d5545e0f79d81832ccd5c8405a70d8daa256f..d59acc729ad5af515b8ef4c98a3edeb440854820 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -45,7 +45,7 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a world, which may contain entities, chunks and blocks
*/
-public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient, Metadatable, PersistentDataHolder, Keyed {
+public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient, Metadatable, PersistentDataHolder, Keyed, net.kyori.adventure.audience.ForwardingAudience { // Paper
/**
* Gets the {@link Block} at the given coordinates
@@ -606,6 +606,14 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
@NotNull
public List<Player> getPlayers();
+ // Paper start
+ @NotNull
+ @Override
+ default Iterable<? extends net.kyori.adventure.audience.Audience> audiences() {
+ return this.getPlayers();
+ }
+ // Paper end
+
/**
* Returns a list of entities within a bounding box centered around a
* Location.
diff --git a/src/main/java/org/bukkit/block/CommandBlock.java b/src/main/java/org/bukkit/block/CommandBlock.java
index 372c0bd5a4d7800a11c24c95e39fe376a96232bf..9c88be68b4f403d0500cb607394b3a1646675ef7 100644
--- a/src/main/java/org/bukkit/block/CommandBlock.java
+++ b/src/main/java/org/bukkit/block/CommandBlock.java
@@ -33,7 +33,9 @@ public interface CommandBlock extends TileState {
* by default is "@".
*
* @return Name of this CommandBlock.
+ * @deprecated in favour of {@link #name()}
*/
+ @Deprecated // Paper
@NotNull
public String getName();
@@ -43,6 +45,28 @@ public interface CommandBlock extends TileState {
* same as setting it to "@".
*
* @param name New name for this CommandBlock.
+ * @deprecated in favour of {@link #name(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setName(@Nullable String name);
+
+ // Paper start
+ /**
+ * Gets the name of this CommandBlock. The name is used with commands
+ * that this CommandBlock executes. This name will never be null, and
+ * by default is a {@link net.kyori.adventure.text.TextComponent} containing {@code @}.
+ *
+ * @return Name of this CommandBlock.
+ */
+ public net.kyori.adventure.text.@NotNull Component name();
+
+ /**
+ * Sets the name of this CommandBlock. The name is used with commands
+ * that this CommandBlock executes. Setting the name to null is the
+ * same as setting it to a {@link net.kyori.adventure.text.TextComponent} containing {@code @}.
+ *
+ * @param name New name for this CommandBlock.
+ */
+ public void name(net.kyori.adventure.text.@Nullable Component name);
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/block/Sign.java b/src/main/java/org/bukkit/block/Sign.java
index 5fc1c759e6e8f3fd43a5fa5c6e3f777efa16b1ec..2813f96bb13b9be28867d2c045a3003a18456879 100644
--- a/src/main/java/org/bukkit/block/Sign.java
+++ b/src/main/java/org/bukkit/block/Sign.java
@@ -10,12 +10,51 @@ import org.jetbrains.annotations.NotNull;
* Represents a captured state of either a SignPost or a WallSign.
*/
public interface Sign extends TileState, Colorable {
+ // Paper start
+ /**
+ * Gets all the lines of text currently on the {@link Side#FRONT} of this sign.
+ *
+ * @return List of components containing each line of text
+ * @deprecated A sign may have multiple writable sides now. Use {@link Sign#getSide(Side)} and {@link SignSide#lines()}.
+ */
+ @NotNull
+ @Deprecated
+ public java.util.List<net.kyori.adventure.text.Component> lines();
+
+ /**
+ * Gets the line of text at the specified index on the {@link Side#FRONT}.
+ * <p>
+ * For example, getLine(0) will return the first line of text.
+ *
+ * @param index Line number to get the text from, starting at 0
+ * @throws IndexOutOfBoundsException Thrown when the line does not exist
+ * @return Text on the given line
+ * @deprecated A sign may have multiple writable sides now. Use {@link #getSide(Side)} and {@link SignSide#line(int)}.
+ */
+ @NotNull
+ @Deprecated
+ public net.kyori.adventure.text.Component line(int index) throws IndexOutOfBoundsException;
+
+ /**
+ * Sets the line of text at the specified index on the {@link Side#FRONT}.
+ * <p>
+ * For example, setLine(0, "Line One") will set the first line of text to
+ * "Line One".
+ *
+ * @param index Line number to set the text at, starting from 0
+ * @param line New text to set at the specified index
+ * @throws IndexOutOfBoundsException If the index is out of the range 0..3
+ * @deprecated A sign may have multiple writable sides now. Use {@link #getSide(Side)} and {@link SignSide#line(int, net.kyori.adventure.text.Component)}.
+ */
+ @Deprecated
+ public void line(int index, net.kyori.adventure.text.@NotNull Component line) throws IndexOutOfBoundsException;
+ // Paper end
/**
* Gets all the lines of text currently on the {@link Side#FRONT} of this sign.
*
* @return Array of Strings containing each line of text
- * @deprecated A sign may have multiple writable sides now. Use {@link Sign#getSide(Side)} and {@link SignSide#getLines()}.
+ * @deprecated A sign may have multiple writable sides now. Use {@link Sign#getSide(Side)} and {@link SignSide#lines()}.
*/
@Deprecated
@NotNull
@@ -29,7 +68,7 @@ public interface Sign extends TileState, Colorable {
* @param index Line number to get the text from, starting at 0
* @return Text on the given line
* @throws IndexOutOfBoundsException Thrown when the line does not exist
- * @deprecated A sign may have multiple writable sides now. Use {@link #getSide(Side)} and {@link SignSide#getLine(int)}.
+ * @deprecated A sign may have multiple writable sides now. Use {@link #getSide(Side)} and {@link SignSide#line(int)}.
*/
@Deprecated
@NotNull
@@ -44,7 +83,7 @@ public interface Sign extends TileState, Colorable {
* @param index Line number to set the text at, starting from 0
* @param line New text to set at the specified index
* @throws IndexOutOfBoundsException If the index is out of the range 0..3
- * @deprecated A sign may have multiple writable sides now. Use {@link #getSide(Side)} and {@link SignSide#setLine(int, String)}.
+ * @deprecated A sign may have multiple writable sides now. Use {@link #getSide(Side)} and {@link SignSide#line(int, net.kyori.adventure.text.Component)}.
*/
@Deprecated
public void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException;
diff --git a/src/main/java/org/bukkit/block/sign/SignSide.java b/src/main/java/org/bukkit/block/sign/SignSide.java
index 0f4ae7bd2ad379b5edb40f49f93de9e18c38f415..575e545a69b5279b90067d7ebee08b7b59288496 100644
--- a/src/main/java/org/bukkit/block/sign/SignSide.java
+++ b/src/main/java/org/bukkit/block/sign/SignSide.java
@@ -7,13 +7,48 @@ import org.jetbrains.annotations.NotNull;
* Represents a side of a sign.
*/
public interface SignSide extends Colorable {
+ // Paper start
+ /**
+ * Gets all the lines of text currently on the sign.
+ *
+ * @return List of components containing each line of text
+ */
+ @NotNull
+ public java.util.List<net.kyori.adventure.text.Component> lines();
+
+ /**
+ * Gets the line of text at the specified index.
+ * <p>
+ * For example, getLine(0) will return the first line of text.
+ *
+ * @param index Line number to get the text from, starting at 0
+ * @throws IndexOutOfBoundsException Thrown when the line does not exist
+ * @return Text on the given line
+ */
+ @NotNull
+ public net.kyori.adventure.text.Component line(int index) throws IndexOutOfBoundsException;
+
+ /**
+ * Sets the line of text at the specified index.
+ * <p>
+ * For example, setLine(0, "Line One") will set the first line of text to
+ * "Line One".
+ *
+ * @param index Line number to set the text at, starting from 0
+ * @param line New text to set at the specified index
+ * @throws IndexOutOfBoundsException If the index is out of the range 0..3
+ */
+ public void line(int index, net.kyori.adventure.text.@NotNull Component line) throws IndexOutOfBoundsException;
+ // Paper end
/**
* Gets all the lines of text currently on this side of the sign.
*
* @return Array of Strings containing each line of text
+ * @deprecated in favour of {@link #lines()}
*/
@NotNull
+ @Deprecated // Paper
public String[] getLines();
/**
@@ -24,8 +59,10 @@ public interface SignSide extends Colorable {
* @param index Line number to get the text from, starting at 0
* @return Text on the given line
* @throws IndexOutOfBoundsException Thrown when the line does not exist
+ * @deprecated in favour of {@link #line(int)}
*/
@NotNull
+ @Deprecated // Paper
public String getLine(int index) throws IndexOutOfBoundsException;
/**
@@ -37,7 +74,9 @@ public interface SignSide extends Colorable {
* @param index Line number to set the text at, starting from 0
* @param line New text to set at the specified index
* @throws IndexOutOfBoundsException If the index is out of the range 0..3
+ * @deprecated in favour of {@link #line(int, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setLine(int index, @NotNull String line) throws IndexOutOfBoundsException;
/**
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
index 80209bb88a0294d4eedc78509533a6257315d856..75759131bd94b672bec4cd8e271ebff1ad391cba 100644
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -32,7 +32,7 @@ public abstract class Command {
protected String description;
protected String usageMessage;
private String permission;
- private String permissionMessage;
+ private net.kyori.adventure.text.Component permissionMessage; // Paper
public org.spigotmc.CustomTimingsHandler timings; // Spigot
protected Command(@NotNull String name) {
@@ -186,10 +186,10 @@ public abstract class Command {
if (permissionMessage == null) {
target.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is a mistake.");
- } else if (permissionMessage.length() != 0) {
- for (String line : permissionMessage.replace("<permission>", permission).split("\n")) {
- target.sendMessage(line);
- }
+ // Paper start - use components for permissionMessage
+ } else if (!permissionMessage.equals(net.kyori.adventure.text.Component.empty())) {
+ target.sendMessage(permissionMessage.replaceText(net.kyori.adventure.text.TextReplacementConfig.builder().matchLiteral("<permission>").replacement(permission).build()));
+ // Paper end
}
return false;
@@ -317,10 +317,12 @@ public abstract class Command {
* command
*
* @return Permission check failed message
+ * @deprecated use {@link #permissionMessage()}
*/
@Nullable
+ @Deprecated // Paper
public String getPermissionMessage() {
- return permissionMessage;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serializeOrNull(permissionMessage); // Paper
}
/**
@@ -381,10 +383,12 @@ public abstract class Command {
* @param permissionMessage new permission message, null to indicate
* default message, or an empty string to indicate no message
* @return this command object, for chaining
+ * @deprecated use {@link #permissionMessage(net.kyori.adventure.text.Component)}
*/
@NotNull
+ @Deprecated // Paper
public Command setPermissionMessage(@Nullable String permissionMessage) {
- this.permissionMessage = permissionMessage;
+ this.permissionMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOrNull(permissionMessage); // Paper
return this;
}
@@ -399,13 +403,47 @@ public abstract class Command {
this.usageMessage = (usage == null) ? "" : usage;
return this;
}
+ // Paper start
+ /**
+ * Gets the permission message.
+ *
+ * @return the permission message
+ */
+ public net.kyori.adventure.text.@Nullable Component permissionMessage() {
+ return this.permissionMessage;
+ }
+
+ /**
+ * Sets the permission message.
+ *
+ * @param permissionMessage the permission message
+ */
+ public void permissionMessage(net.kyori.adventure.text.@Nullable Component permissionMessage) {
+ this.permissionMessage = permissionMessage;
+ }
+ // Paper end
public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull String message) {
broadcastCommandMessage(source, message, true);
}
public static void broadcastCommandMessage(@NotNull CommandSender source, @NotNull String message, boolean sendToSource) {
- String result = source.getName() + ": " + message;
+ // Paper start
+ broadcastCommandMessage(source, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message), sendToSource);
+ }
+
+ public static void broadcastCommandMessage(@NotNull CommandSender source, net.kyori.adventure.text.@NotNull Component message) {
+ broadcastCommandMessage(source, message, true);
+ }
+
+ public static void broadcastCommandMessage(@NotNull CommandSender source, net.kyori.adventure.text.@NotNull Component message, boolean sendToSource) {
+ net.kyori.adventure.text.TextComponent.Builder result = net.kyori.adventure.text.Component.text()
+ .color(net.kyori.adventure.text.format.NamedTextColor.WHITE)
+ .decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false)
+ .append(source.name())
+ .append(net.kyori.adventure.text.Component.text(": "))
+ .append(message);
+ // Paper end
if (source instanceof BlockCommandSender) {
BlockCommandSender blockCommandSender = (BlockCommandSender) source;
@@ -424,7 +462,12 @@ public abstract class Command {
}
Set<Permissible> users = Bukkit.getPluginManager().getPermissionSubscriptions(Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
- String colored = ChatColor.GRAY + "" + ChatColor.ITALIC + "[" + result + ChatColor.GRAY + ChatColor.ITALIC + "]";
+ // Paper start
+ net.kyori.adventure.text.TextComponent.Builder colored = net.kyori.adventure.text.Component.text()
+ .color(net.kyori.adventure.text.format.NamedTextColor.GRAY)
+ .decorate(net.kyori.adventure.text.format.TextDecoration.ITALIC)
+ .append(net.kyori.adventure.text.Component.text("["), result, net.kyori.adventure.text.Component.text("]"));
+ // Paper end
if (sendToSource && !(source instanceof ConsoleCommandSender)) {
source.sendMessage(message);
diff --git a/src/main/java/org/bukkit/command/CommandSender.java b/src/main/java/org/bukkit/command/CommandSender.java
index 284be63a125624a8ae43d2c164aede810ce6bfe5..70fec73328227725f519af845ecbdce8be2fa4e2 100644
--- a/src/main/java/org/bukkit/command/CommandSender.java
+++ b/src/main/java/org/bukkit/command/CommandSender.java
@@ -6,20 +6,28 @@ import org.bukkit.permissions.Permissible;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-public interface CommandSender extends Permissible {
+public interface CommandSender extends net.kyori.adventure.audience.Audience, Permissible { // Paper
/**
* Sends this sender a message
*
* @param message Message to be displayed
+ * @see #sendMessage(net.kyori.adventure.text.Component)
+ * @see #sendPlainMessage(String)
+ * @see #sendRichMessage(String)
*/
+ @org.jetbrains.annotations.ApiStatus.Obsolete // Paper
public void sendMessage(@NotNull String message);
/**
* Sends this sender multiple messages
*
* @param messages An array of messages to be displayed
+ * @see #sendMessage(net.kyori.adventure.text.Component)
+ * @see #sendPlainMessage(String)
+ * @see #sendRichMessage(String)
*/
+ @org.jetbrains.annotations.ApiStatus.Obsolete // Paper
public void sendMessage(@NotNull String... messages);
/**
@@ -27,7 +35,10 @@ public interface CommandSender extends Permissible {
*
* @param message Message to be displayed
* @param sender The sender of this message
+ * @see #sendMessage(net.kyori.adventure.identity.Identified, net.kyori.adventure.text.Component)
+ * @deprecated sender UUID is ignored
*/
+ @Deprecated // Paper
public void sendMessage(@Nullable UUID sender, @NotNull String message);
/**
@@ -35,7 +46,10 @@ public interface CommandSender extends Permissible {
*
* @param messages An array of messages to be displayed
* @param sender The sender of this message
+ * @see #sendMessage(net.kyori.adventure.identity.Identified, net.kyori.adventure.text.Component)
+ * @deprecated sender UUID is ignored
*/
+ @Deprecated // Paper
public void sendMessage(@Nullable UUID sender, @NotNull String... messages);
/**
@@ -61,7 +75,9 @@ public interface CommandSender extends Permissible {
* Sends this sender a chat component.
*
* @param component the components to send
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
*/
+ @Deprecated // Paper
public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -70,7 +86,9 @@ public interface CommandSender extends Permissible {
* Sends an array of components as a single message to the sender.
*
* @param components the components to send
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
*/
+ @Deprecated // Paper
public void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -80,7 +98,9 @@ public interface CommandSender extends Permissible {
*
* @param component the components to send
* @param sender the sender of the message
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
*/
+ @Deprecated // Paper
public void sendMessage(@Nullable UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent component) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -90,7 +110,9 @@ public interface CommandSender extends Permissible {
*
* @param components the components to send
* @param sender the sender of the message
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
*/
+ @Deprecated // Paper
public void sendMessage(@Nullable UUID sender, @NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -99,4 +121,52 @@ public interface CommandSender extends Permissible {
@NotNull
Spigot spigot();
// Spigot end
+
+ // Paper start
+ /**
+ * Gets the name of this command sender
+ *
+ * @return Name of the sender
+ */
+ public net.kyori.adventure.text.@NotNull Component name();
+
+ @Override
+ default void sendMessage(final net.kyori.adventure.identity.@NotNull Identity identity, final net.kyori.adventure.text.@NotNull Component message, final net.kyori.adventure.audience.@NotNull MessageType type) {
+ this.sendMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(message));
+ }
+
+ /**
+ * Sends a message with the MiniMessage format to the command sender.
+ * <p>
+ * See <a href="https://docs.advntr.dev/minimessage/">MiniMessage docs</a>
+ * for more information on the format.
+ *
+ * @param message MiniMessage content
+ */
+ default void sendRichMessage(final @NotNull String message) {
+ this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message));
+ }
+
+ /**
+ * Sends a message with the MiniMessage format to the command sender.
+ * <p>
+ * See <a href="https://docs.advntr.dev/minimessage/">MiniMessage docs</a> and <a href="https://docs.advntr.dev/minimessage/dynamic-replacements">MiniMessage Placeholders docs</a>
+ * for more information on the format.
+ *
+ * @param message MiniMessage content
+ * @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));
+ }
+
+ /**
+ * Sends a plain message to the command sender.
+ *
+ * @param message plain message
+ */
+ default void sendPlainMessage(final @NotNull String message) {
+ this.sendMessage(net.kyori.adventure.text.Component.text(message));
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/command/PluginCommandYamlParser.java b/src/main/java/org/bukkit/command/PluginCommandYamlParser.java
index a542c4bb3c973bbe4b976642feccde6a4d90cb7b..ef870b864c1e36032b54b31f3f85707edc06d764 100644
--- a/src/main/java/org/bukkit/command/PluginCommandYamlParser.java
+++ b/src/main/java/org/bukkit/command/PluginCommandYamlParser.java
@@ -67,7 +67,7 @@ public class PluginCommandYamlParser {
}
if (permissionMessage != null) {
- newCmd.setPermissionMessage(permissionMessage.toString());
+ newCmd.permissionMessage(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(permissionMessage.toString())); // Paper
}
pluginCmds.add(newCmd);
diff --git a/src/main/java/org/bukkit/command/ProxiedCommandSender.java b/src/main/java/org/bukkit/command/ProxiedCommandSender.java
index fcc34b640265f4dccb46b9f09466ab8e1d96043e..5c813ac024f675951159a59d88d8baa0d49840e9 100644
--- a/src/main/java/org/bukkit/command/ProxiedCommandSender.java
+++ b/src/main/java/org/bukkit/command/ProxiedCommandSender.java
@@ -3,7 +3,7 @@ package org.bukkit.command;
import org.jetbrains.annotations.NotNull;
-public interface ProxiedCommandSender extends CommandSender {
+public interface ProxiedCommandSender extends CommandSender, net.kyori.adventure.audience.ForwardingAudience.Single { // Paper
/**
* Returns the CommandSender which triggered this proxied command
@@ -21,4 +21,16 @@ public interface ProxiedCommandSender extends CommandSender {
@NotNull
CommandSender getCallee();
+ // Paper start
+ @Override
+ default void sendMessage(final net.kyori.adventure.identity.@NotNull Identity source, final net.kyori.adventure.text.@NotNull Component message, final net.kyori.adventure.audience.@NotNull MessageType type) {
+ net.kyori.adventure.audience.ForwardingAudience.Single.super.sendMessage(source, message, type);
+ }
+
+ @NotNull
+ @Override
+ default net.kyori.adventure.audience.Audience audience() {
+ return this.getCaller();
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/conversations/Conversable.java b/src/main/java/org/bukkit/conversations/Conversable.java
index b7d8dd30360a38dbdc7bbce40c8e6ced7261f833..0817f2395c2b18828565435568ce651f5ba99a99 100644
--- a/src/main/java/org/bukkit/conversations/Conversable.java
+++ b/src/main/java/org/bukkit/conversations/Conversable.java
@@ -55,6 +55,7 @@ public interface Conversable {
*
* @param message Message to be displayed
*/
+ @org.jetbrains.annotations.ApiStatus.Obsolete // Paper
public void sendRawMessage(@NotNull String message);
/**
@@ -62,6 +63,8 @@ public interface Conversable {
*
* @param message Message to be displayed
* @param sender The sender of this message
+ * @deprecated sender UUID is ignored
*/
+ @Deprecated // Paper
public void sendRawMessage(@Nullable UUID sender, @NotNull String message);
}
diff --git a/src/main/java/org/bukkit/enchantments/Enchantment.java b/src/main/java/org/bukkit/enchantments/Enchantment.java
index c349cd16de02981392a8788ddaa3152e901aacff..6a915b5b41daa5ea64913a2d5c611a6167168395 100644
--- a/src/main/java/org/bukkit/enchantments/Enchantment.java
+++ b/src/main/java/org/bukkit/enchantments/Enchantment.java
@@ -295,6 +295,19 @@ public abstract class Enchantment implements Keyed {
* @return True if the enchantment may be applied, otherwise False
*/
public abstract boolean canEnchantItem(@NotNull ItemStack item);
+ // Paper start
+ /**
+ * Get the name of the enchantment with its applied level.
+ * <p>
+ * If the given {@code level} is either less than the {@link #getStartLevel()} or greater than the {@link #getMaxLevel()},
+ * the level may not be shown in the numeral format one may otherwise expect.
+ * </p>
+ *
+ * @param level the level of the enchantment to show
+ * @return the name of the enchantment with {@code level} applied
+ */
+ public abstract net.kyori.adventure.text.@NotNull Component displayName(int level);
+ // Paper end
/**
* Gets the Enchantment at the specified key
diff --git a/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java b/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java
index 7ad7bcf9a9333c8d6d1d7cab53a6d457ec20bbf6..c4f86ba1037f3f0e5d697a0962d71d6f8c7c1fbe 100644
--- a/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java
+++ b/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java
@@ -20,4 +20,11 @@ public abstract class EnchantmentWrapper extends Enchantment {
public Enchantment getEnchantment() {
return this;
}
+ // Paper start
+ @NotNull
+ @Override
+ public net.kyori.adventure.text.Component displayName(int level) {
+ return getEnchantment().displayName(level);
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index 8532b8484d5a493c1c37ad7508597f624f1831c8..978431fd88cfb7d42fcdea8c904633df5c64daed 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
* Not all methods are guaranteed to work/may have side effects when
* {@link #isInWorld()} is false.
*/
-public interface Entity extends Metadatable, CommandSender, Nameable, PersistentDataHolder {
+public interface Entity extends Metadatable, CommandSender, Nameable, PersistentDataHolder, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowEntity>, net.kyori.adventure.sound.Sound.Emitter { // Paper
/**
* Gets the entity's current position
@@ -768,4 +768,20 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
@Override
Spigot spigot();
// Spigot end
+
+ // Paper start
+ /**
+ * Gets the entity's display name formatted with their team prefix/suffix and
+ * the entity's default hover/click events.
+ *
+ * @return the team display name
+ */
+ net.kyori.adventure.text.@NotNull Component teamDisplayName();
+
+ @NotNull
+ @Override
+ default net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowEntity> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowEntity> 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.customName())));
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index a5046b416fa26d51974de0866d3af190ee197c3a..01fe25d7925d7c014524ae9c26b62fade5670e64 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -52,7 +52,41 @@ import org.jetbrains.annotations.Nullable;
/**
* Represents a player, connected or not
*/
-public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient {
+public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, net.kyori.adventure.bossbar.BossBarViewer { // Paper
+
+ // Paper start
+ @Override
+ default net.kyori.adventure.identity.@NotNull Identity identity() {
+ return net.kyori.adventure.identity.Identity.identity(this.getUniqueId());
+ }
+
+ /**
+ * Gets an unmodifiable view of all known currently active bossbars.
+ * <p>
+ * <b>This currently only returns bossbars shown to the player via
+ * {@link #showBossBar(net.kyori.adventure.bossbar.BossBar)} and does not contain bukkit
+ * {@link org.bukkit.boss.BossBar} instances shown to the player.</b>
+ *
+ * @return an unmodifiable view of all known currently active bossbars
+ * @since 4.14.0
+ */
+ @Override
+ @org.jetbrains.annotations.UnmodifiableView @NotNull Iterable<? extends net.kyori.adventure.bossbar.BossBar> activeBossBars();
+
+ /**
+ * Gets the "friendly" name to display of this player.
+ *
+ * @return the display name
+ */
+ net.kyori.adventure.text.@NotNull Component displayName();
+
+ /**
+ * Sets the "friendly" name to display of this player.
+ *
+ * @param displayName the display name to set
+ */
+ void displayName(final net.kyori.adventure.text.@Nullable Component displayName);
+ // Paper end
/**
* {@inheritDoc}
@@ -69,7 +103,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* places defined by plugins.
*
* @return the friendly name
+ * @deprecated in favour of {@link #displayName()}
*/
+ @Deprecated // Paper
@NotNull
public String getDisplayName();
@@ -81,15 +117,50 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* places defined by plugins.
*
* @param name The new display name.
+ * @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setDisplayName(@Nullable String name);
+ // Paper start
+ /**
+ * Sets the name that is shown on the in-game player list.
+ * <p>
+ * If the value is null, the name will be identical to {@link #getName()}.
+ *
+ * @param name new player list name
+ */
+ void playerListName(net.kyori.adventure.text.@Nullable Component name);
+
+ /**
+ * Gets the name that is shown on the in-game player list.
+ *
+ * @return the player list name
+ */
+ net.kyori.adventure.text.@NotNull Component playerListName();
+
+ /**
+ * Gets the currently displayed player list header for this player.
+ *
+ * @return player list header or null
+ */
+ net.kyori.adventure.text.@Nullable Component playerListHeader();
+
+ /**
+ * Gets the currently displayed player list footer for this player.
+ *
+ * @return player list footer or null
+ */
+ net.kyori.adventure.text.@Nullable Component playerListFooter();
+ // Paper end
/**
* Gets the name that is shown on the player list.
*
* @return the player list name
+ * @deprecated in favour of {@link #playerListName()}
*/
@NotNull
+ @Deprecated // Paper
public String getPlayerListName();
/**
@@ -98,14 +169,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* If the value is null, the name will be identical to {@link #getName()}.
*
* @param name new player list name
+ * @deprecated in favour of {@link #playerListName(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setPlayerListName(@Nullable String name);
/**
* Gets the currently displayed player list header for this player.
*
* @return player list header or null
+ * @deprecated in favour of {@link #playerListHeader()}
*/
+ @Deprecated // Paper
@Nullable
public String getPlayerListHeader();
@@ -113,7 +188,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* Gets the currently displayed player list footer for this player.
*
* @return player list header or null
+ * @deprecated in favour of {@link #playerListFooter()}
*/
+ @Deprecated // Paper
@Nullable
public String getPlayerListFooter();
@@ -121,14 +198,18 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* Sets the currently displayed player list header for this player.
*
* @param header player list header, null for empty
+ * @deprecated in favour of {@link #sendPlayerListHeader(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setPlayerListHeader(@Nullable String header);
/**
* Sets the currently displayed player list footer for this player.
*
* @param footer player list footer, null for empty
+ * @deprecated in favour of {@link #sendPlayerListFooter(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setPlayerListFooter(@Nullable String footer);
/**
@@ -137,7 +218,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*
* @param header player list header, null for empty
* @param footer player list footer, null for empty
+ * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setPlayerListHeaderFooter(@Nullable String header, @Nullable String footer);
/**
@@ -175,9 +258,25 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* Kicks player with custom kick message.
*
* @param message kick message
+ * @deprecated in favour of {@link #kick(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void kickPlayer(@Nullable String message);
+ // Paper start
+ /**
+ * Kicks the player with the default kick message.
+ * @see #kick(net.kyori.adventure.text.Component)
+ */
+ void kick();
+ /**
+ * Kicks player with custom kick message.
+ *
+ * @param message kick message
+ */
+ void kick(final net.kyori.adventure.text.@Nullable Component message);
+ // Paper end
+
/**
* Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will
* update the entry.
@@ -799,6 +898,106 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public void sendEquipmentChange(@NotNull LivingEntity entity, @NotNull Map<EquipmentSlot, ItemStack> items);
+ // Paper start
+ /**
+ * Send a sign change. This fakes a sign change packet for a user at
+ * a certain location. This will not actually change the world in any way.
+ * This method will use a sign at the location's block or a faked sign
+ * sent via
+ * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}.
+ * <p>
+ * If the client does not have a sign at the given location it will
+ * display an error message to the user.
+ *
+ * @param loc the location of the sign
+ * @param lines the new text on the sign or null to clear it
+ * @throws IllegalArgumentException if location is null
+ * @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (constructed e.g. via {@link Material#createBlockData()})
+ */
+ @Deprecated
+ default void sendSignChange(@NotNull Location loc, @Nullable java.util.List<? extends net.kyori.adventure.text.Component> lines) throws IllegalArgumentException {
+ this.sendSignChange(loc, lines, DyeColor.BLACK);
+ }
+
+ /**
+ * Send a sign change. This fakes a sign change packet for a user at
+ * a certain location. This will not actually change the world in any way.
+ * This method will use a sign at the location's block or a faked sign
+ * sent via
+ * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}.
+ * <p>
+ * If the client does not have a sign at the given location it will
+ * display an error message to the user.
+ *
+ * @param loc the location of the sign
+ * @param lines the new text on the sign or null to clear it
+ * @param dyeColor the color of the sign
+ * @throws IllegalArgumentException if location is null
+ * @throws IllegalArgumentException if dyeColor is null
+ * @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (constructed e.g. via {@link Material#createBlockData()})
+ */
+ @Deprecated
+ default void sendSignChange(@NotNull Location loc, @Nullable java.util.List<? extends net.kyori.adventure.text.Component> lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException {
+ this.sendSignChange(loc, lines, dyeColor, false);
+ }
+
+ /**
+ * Send a sign change. This fakes a sign change packet for a user at
+ * a certain location. This will not actually change the world in any way.
+ * This method will use a sign at the location's block or a faked sign
+ * sent via
+ * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}.
+ * <p>
+ * If the client does not have a sign at the given location it will
+ * display an error message to the user.
+ *
+ * @param loc the location of the sign
+ * @param lines the new text on the sign or null to clear it
+ * @param hasGlowingText whether the text of the sign should glow as if dyed with a glowing ink sac
+ * @throws IllegalArgumentException if location is null
+ * @throws IllegalArgumentException if dyeColor is null
+ * @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (constructed e.g. via {@link Material#createBlockData()})
+ */
+ @Deprecated
+ default void sendSignChange(@NotNull Location loc, @Nullable java.util.List<? extends net.kyori.adventure.text.Component> lines, boolean hasGlowingText) throws IllegalArgumentException {
+ this.sendSignChange(loc, lines, DyeColor.BLACK, hasGlowingText);
+ }
+
+ /**
+ * Send a sign change. This fakes a sign change packet for a user at
+ * a certain location. This will not actually change the world in any way.
+ * This method will use a sign at the location's block or a faked sign
+ * sent via
+ * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}.
+ * <p>
+ * If the client does not have a sign at the given location it will
+ * display an error message to the user.
+ *
+ * @param loc the location of the sign
+ * @param lines the new text on the sign or null to clear it
+ * @param dyeColor the color of the sign
+ * @param hasGlowingText whether the text of the sign should glow as if dyed with a glowing ink sac
+ * @throws IllegalArgumentException if location is null
+ * @throws IllegalArgumentException if dyeColor is null
+ * @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (constructed e.g. via {@link Material#createBlockData()})
+ */
+ @Deprecated
+ void sendSignChange(@NotNull Location loc, @Nullable java.util.List<? extends net.kyori.adventure.text.Component> lines, @NotNull DyeColor dyeColor, boolean hasGlowingText)
+ throws IllegalArgumentException;
+ // Paper end
+
/**
* Send a sign change. This fakes a sign change packet for a user at
* a certain location. This will not actually change the world in any way.
@@ -816,7 +1015,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @param lines the new text on the sign or null to clear it
* @throws IllegalArgumentException if location is null
* @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (constructed e.g. via {@link Material#createBlockData()})
*/
+ @Deprecated // Paper
public void sendSignChange(@NotNull Location loc, @Nullable String[] lines) throws IllegalArgumentException;
/**
@@ -838,7 +1041,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException if location is null
* @throws IllegalArgumentException if dyeColor is null
* @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (constructed e.g. via {@link Material#createBlockData()})
*/
+ @Deprecated // Paper
public void sendSignChange(@NotNull Location loc, @Nullable String[] lines, @NotNull DyeColor dyeColor) throws IllegalArgumentException;
/**
@@ -861,7 +1068,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException if location is null
* @throws IllegalArgumentException if dyeColor is null
* @throws IllegalArgumentException if lines is non-null and has a length less than 4
+ * @deprecated Use {@link #sendBlockUpdate(Location, TileState)} by creating a new virtual
+ * {@link org.bukkit.block.Sign} block state via {@link BlockData#createBlockState()}
+ * (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;
/**
@@ -1309,7 +1520,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException Thrown if the URL is null.
* @throws IllegalArgumentException Thrown if the URL is too long.
* @deprecated Minecraft no longer uses textures packs. Instead you
- * should use {@link #setResourcePack(String)}.
+ * should use {@link #setResourcePack(UUID, String, byte[], net.kyori.adventure.text.Component, boolean)}.
*/
@Deprecated
public void setTexturePack(@NotNull String url);
@@ -1345,7 +1556,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException Thrown if the URL is null.
* @throws IllegalArgumentException Thrown if the URL is too long. The
* length restriction is an implementation specific arbitrary value.
+ * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
*/
+ @Deprecated // Paper - adventure
public void setResourcePack(@NotNull String url);
/**
@@ -1377,6 +1590,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* pack correctly.
* </ul>
*
+ * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
* @param url The URL from which the client will download the resource
* pack. The string must contain only US-ASCII characters and should
* be encoded as per RFC 1738.
@@ -1389,6 +1603,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException Thrown if the hash is not 20 bytes
* long.
*/
+ @Deprecated // Paper - adventure
public void setResourcePack(@NotNull String url, @Nullable byte[] hash);
/**
@@ -1413,12 +1628,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* {@link PlayerResourcePackStatusEvent} to figure out whether or not
* the player loaded the pack!
* <li>To remove a resource pack you can use
- * {@link #removeResourcePack(UUID)} or {@link #removeResourcePacks()}.
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
* <li>The request is sent with empty string as the hash when the hash is
* not provided. This might result in newer versions not loading the
* pack correctly.
* </ul>
*
+ * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
* @param url The URL from which the client will download the resource
* pack. The string must contain only US-ASCII characters and should
* be encoded as per RFC 1738.
@@ -1432,8 +1648,57 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException Thrown if the hash is not 20 bytes
* long.
*/
+ @Deprecated // Paper - adventure
public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt);
+ // Paper start
+ /**
+ * Request that the player's client download and switch resource packs.
+ * <p>
+ * The player's client will download the new resource pack asynchronously
+ * in the background, and will automatically switch to it once the
+ * download is complete. If the client has downloaded and cached a
+ * resource pack with the same hash in the past it will not download but
+ * directly apply the cached pack. If the hash is null and the client has
+ * downloaded and cached the same resource pack in the past, it will
+ * perform a file size check against the response content to determine if
+ * the resource pack has changed and needs to be downloaded again. When
+ * this request is sent for the very first time from a given server, the
+ * client will first display a confirmation GUI to the player before
+ * proceeding with the download.
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>Players can disable server resources on their client, in which
+ * case this method will have no affect on them. Use the
+ * {@link PlayerResourcePackStatusEvent} to figure out whether or not
+ * the player loaded the pack!
+ * <li>To remove a resource pack you can use
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
+ * <li>The request is sent with empty string as the hash when the hash is
+ * not provided. This might result in newer versions not loading the
+ * pack correctly.
+ * </ul>
+ *
+ * @param url The URL from which the client will download the resource
+ * pack. The string must contain only US-ASCII characters and should
+ * be encoded as per RFC 1738.
+ * @param hash The sha1 hash sum of the resource pack file which is used
+ * to apply a cached version of the pack directly without downloading
+ * if it is available. Hast to be 20 bytes long!
+ * @param prompt The optional custom prompt message to be shown to client.
+ * @throws IllegalArgumentException Thrown if the URL is null.
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
+ * length restriction is an implementation specific arbitrary value.
+ * @throws IllegalArgumentException Thrown if the hash is not 20 bytes
+ * 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) {
+ this.setResourcePack(url, hash, prompt, false);
+ }
+ // Paper end
+
/**
* Request that the player's client download and switch resource packs.
* <p>
@@ -1456,7 +1721,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* {@link PlayerResourcePackStatusEvent} to figure out whether or not
* the player loaded the pack!
* <li>To remove a resource pack you can use
- * {@link #removeResourcePack(UUID)} or {@link #removeResourcePacks()}.
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
* <li>The request is sent with empty string as the hash when the hash is
* not provided. This might result in newer versions not loading the
* pack correctly.
@@ -1475,7 +1740,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* length restriction is an implementation specific arbitrary value.
* @throws IllegalArgumentException Thrown if the hash is not 20 bytes
* long.
+ * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
*/
+ @Deprecated // Paper - adventure
public void setResourcePack(@NotNull String url, @Nullable byte[] hash, boolean force);
/**
@@ -1500,7 +1767,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* {@link PlayerResourcePackStatusEvent} to figure out whether or not
* the player loaded the pack!
* <li>To remove a resource pack you can use
- * {@link #removeResourcePack(UUID)} or {@link #removeResourcePacks()}.
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
* <li>The request is sent with empty string as the hash when the hash is
* not provided. This might result in newer versions not loading the
* pack correctly.
@@ -1520,9 +1787,61 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* length restriction is an implementation specific arbitrary value.
* @throws IllegalArgumentException Thrown if the hash is not 20 bytes
* long.
+ * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
*/
+ @Deprecated // Paper
public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force);
+ // Paper start
+ /**
+ * Request that the player's client download and switch resource packs.
+ * <p>
+ * The player's client will download the new resource pack asynchronously
+ * in the background, and will automatically switch to it once the
+ * download is complete. If the client has downloaded and cached a
+ * resource pack with the same hash in the past it will not download but
+ * directly apply the cached pack. If the hash is null and the client has
+ * downloaded and cached the same resource pack in the past, it will
+ * perform a file size check against the response content to determine if
+ * the resource pack has changed and needs to be downloaded again. When
+ * this request is sent for the very first time from a given server, the
+ * client will first display a confirmation GUI with a custom prompt
+ * to the player before proceeding with the download.
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>Players can disable server resources on their client, in which
+ * case this method will have no affect on them. Use the
+ * {@link PlayerResourcePackStatusEvent} to figure out whether or not
+ * the player loaded the pack!
+ * <li>To remove a resource pack you can use
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
+ * <li>The request is sent with empty string as the hash when the hash is
+ * not provided. This might result in newer versions not loading the
+ * pack correctly.
+ * </ul>
+ *
+ * @param url The URL from which the client will download the resource
+ * pack. The string must contain only US-ASCII characters and should
+ * be encoded as per RFC 1738.
+ * @param hash The sha1 hash sum of the resource pack file which is used
+ * to apply a cached version of the pack directly without downloading
+ * if it is available. Hast to be 20 bytes long!
+ * @param prompt The optional custom prompt message to be shown to client.
+ * @param force If true, the client will be disconnected from the server
+ * when it declines to use the resource pack.
+ * @throws IllegalArgumentException Thrown if the URL is null.
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
+ * length restriction is an implementation specific arbitrary value.
+ * @throws IllegalArgumentException Thrown if the hash is not 20 bytes
+ * 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) {
+ this.setResourcePack(UUID.nameUUIDFromBytes(url.getBytes(java.nio.charset.StandardCharsets.UTF_8)), url, hash, prompt, force);
+ }
+ // Paper end
+
/**
* Request that the player's client download and switch resource packs.
* <p>
@@ -1545,7 +1864,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* {@link PlayerResourcePackStatusEvent} to figure out whether or not
* the player loaded the pack!
* <li>To remove a resource pack you can use
- * {@link #removeResourcePack(UUID)} or {@link #removeResourcePacks()}.
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
* <li>The request is sent with empty string as the hash when the hash is
* not provided. This might result in newer versions not loading the
* pack correctly.
@@ -1566,21 +1885,74 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* length restriction is an implementation specific arbitrary value.
* @throws IllegalArgumentException Thrown if the hash is not 20 bytes
* long.
+ * @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
*/
+ @Deprecated // Paper - adventure
public void setResourcePack(@NotNull UUID id, @NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force);
+ // Paper start
+ /**
+ * Request that the player's client download and switch resource packs.
+ * <p>
+ * The player's client will download the new resource pack asynchronously
+ * in the background, and will automatically switch to it once the
+ * download is complete. If the client has downloaded and cached a
+ * resource pack with the same hash in the past it will not download but
+ * directly apply the cached pack. If the hash is null and the client has
+ * downloaded and cached the same resource pack in the past, it will
+ * perform a file size check against the response content to determine if
+ * the resource pack has changed and needs to be downloaded again. When
+ * this request is sent for the very first time from a given server, the
+ * client will first display a confirmation GUI to the player before
+ * proceeding with the download.
+ * <p>
+ * Notes:
+ * <ul>
+ * <li>Players can disable server resources on their client, in which
+ * case this method will have no affect on them. Use the
+ * {@link PlayerResourcePackStatusEvent} to figure out whether or not
+ * the player loaded the pack!
+ * <li>To remove a resource pack you can use
+ * {@link #removeResourcePacks(UUID, UUID...)} or {@link #clearResourcePacks()}.
+ * <li>The request is sent with empty string as the hash when the hash is
+ * not provided. This might result in newer versions not loading the
+ * pack correctly.
+ * </ul>
+ *
+ * @param uuid Unique resource pack ID.
+ * @param url The URL from which the client will download the resource
+ * pack. The string must contain only US-ASCII characters and should
+ * be encoded as per RFC 1738.
+ * @param hash The sha1 hash sum of the resource pack file which is used
+ * to apply a cached version of the pack directly without downloading
+ * if it is available. Hast to be 20 bytes long!
+ * @param prompt The optional custom prompt message to be shown to client.
+ * @param force If true, the client will be disconnected from the server
+ * when it declines to use the resource pack.
+ * @throws IllegalArgumentException Thrown if the URL is null.
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
+ * length restriction is an implementation specific arbitrary value.
+ * @throws IllegalArgumentException Thrown if the hash is not 20 bytes
+ * 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);
+ // Paper end
+
/**
* Request that the player's client remove a resource pack sent by the
* server.
*
* @param id the id of the resource pack.
* @throws IllegalArgumentException If the ID is null.
+ * @see #removeResourcePacks(UUID, UUID...)
*/
public void removeResourcePack(@NotNull UUID id);
/**
* Request that the player's client remove all loaded resource pack sent by
* the server.
+ * @see #clearResourcePacks()
*/
public void removeResourcePacks();
@@ -1718,7 +2090,7 @@ 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);
@@ -1737,7 +2109,9 @@ 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);
/**
@@ -1964,6 +2338,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public int getClientViewDistance();
+ // Paper start
+ /**
+ * Gets the player's current locale.
+ *
+ * @return the player's locale
+ */
+ @NotNull java.util.Locale locale();
+ // Paper end
/**
* Gets the player's estimated ping in milliseconds.
*
@@ -1989,8 +2371,10 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* they wish.
*
* @return the player's locale
+ * @deprecated in favour of {@link #locale()}
*/
@NotNull
+ @Deprecated // Paper
public String getLocale();
/**
@@ -2042,6 +2426,14 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public boolean isAllowingServerListings();
+ // Paper start
+ @NotNull
+ @Override
+ default net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowEntity> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowEntity> 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
+
// Spigot start
public class Spigot extends Entity.Spigot {
@@ -2073,11 +2465,13 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Deprecated // Paper
@Override
public void sendMessage(@NotNull 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) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -2088,7 +2482,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*
* @param position the screen position
* @param component the components to send
+ * @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) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -2098,7 +2494,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*
* @param position the screen position
* @param components the components to send
+ * @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) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -2109,7 +2507,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @param position the screen position
* @param sender the sender of the message
* @param component the components to send
+ * @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) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -2120,7 +2520,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @param position the screen position
* @param sender the sender of the message
* @param components the components to send
+ * @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) {
throw new UnsupportedOperationException("Not supported yet.");
}
diff --git a/src/main/java/org/bukkit/entity/TextDisplay.java b/src/main/java/org/bukkit/entity/TextDisplay.java
index d6d7ada3d3ff9a033ce3f780b104ef3e176f9083..f101ffde9e7b3f6c3ab6f1cffb8d6f4e720634b2 100644
--- a/src/main/java/org/bukkit/entity/TextDisplay.java
+++ b/src/main/java/org/bukkit/entity/TextDisplay.java
@@ -13,17 +13,37 @@ public interface TextDisplay extends Display {
* Gets the displayed text.
*
* @return the displayed text.
+ * @deprecated in favour of {@link #text()}
*/
@Nullable
+ @Deprecated // Paper
String getText();
/**
* Sets the displayed text.
*
* @param text the new text
+ * @deprecated in favour of {@link #text(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setText(@Nullable String text);
+ // Paper start
+ /**
+ * Gets the displayed text.
+ *
+ * @return the displayed text
+ */
+ net.kyori.adventure.text.@NotNull Component text();
+
+ /**
+ * Sets the displayed text.
+ *
+ * @param text the new text
+ */
+ void text(net.kyori.adventure.text.@Nullable Component text);
+ // Paper end
+
/**
* Gets the maximum line width before wrapping.
*
diff --git a/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java b/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java
index 63c80b4ee1f7adc8a9efc3b607993104b1991f90..91cab8b13d5bba34007f124838b32a1df58c5ac7 100644
--- a/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java
+++ b/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java
@@ -32,7 +32,9 @@ public interface CommandMinecart extends Minecart {
* same as setting it to "@".
*
* @param name New name for this CommandMinecart.
+ * @deprecated in favour of {@link #customName(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setName(@Nullable String name);
}
diff --git a/src/main/java/org/bukkit/event/block/SignChangeEvent.java b/src/main/java/org/bukkit/event/block/SignChangeEvent.java
index f4ac033ff8794a61c82a49dc6c3f863f3291455d..d944d67f544494355f03c5bc9afd8ea7726e6412 100644
--- a/src/main/java/org/bukkit/event/block/SignChangeEvent.java
+++ b/src/main/java/org/bukkit/event/block/SignChangeEvent.java
@@ -17,18 +17,38 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final Player player;
- private final String[] lines;
+ private final java.util.List<net.kyori.adventure.text.Component> adventure$lines; // Paper
private final Side side;
+ // Paper start
+ public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player player, @NotNull final java.util.List<net.kyori.adventure.text.Component> adventure$lines, @NotNull Side side) {
+ super(theBlock);
+ this.player = player;
+ this.adventure$lines = adventure$lines;
+ this.side = side;
+ }
+
+ @Deprecated
+ public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player player, @NotNull final java.util.List<net.kyori.adventure.text.Component> adventure$lines) {
+ this(theBlock, player, adventure$lines, Side.FRONT);
+ }
+ // Paper end
+
@Deprecated
public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player thePlayer, @NotNull final String[] theLines) {
this(theBlock, thePlayer, theLines, Side.FRONT);
}
+ @Deprecated // Paper
public SignChangeEvent(@NotNull final Block theBlock, @NotNull final Player thePlayer, @NotNull final String[] theLines, @NotNull Side side) {
super(theBlock);
this.player = thePlayer;
- this.lines = theLines;
+ // Paper start
+ this.adventure$lines = new java.util.ArrayList<>();
+ for (String theLine : theLines) {
+ this.adventure$lines.add(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(theLine));
+ }
+ // Paper end
this.side = side;
}
@@ -42,14 +62,52 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
return player;
}
+ // Paper start
+ /**
+ * Gets all of the lines of text from the sign involved in this event.
+ *
+ * @return the String array for the sign's lines new text
+ */
+ public @NotNull java.util.List<net.kyori.adventure.text.Component> lines() {
+ return this.adventure$lines;
+ }
+
+ /**
+ * Gets a single line of text from the sign involved in this event.
+ *
+ * @param index index of the line to get
+ * @return the String containing the line of text associated with the
+ * provided index
+ * @throws IndexOutOfBoundsException thrown when the provided index is {@literal > 3
+ * or < 0}
+ */
+ public net.kyori.adventure.text.@Nullable Component line(int index) throws IndexOutOfBoundsException {
+ return this.adventure$lines.get(index);
+ }
+
+ /**
+ * Sets a single line for the sign involved in this event
+ *
+ * @param index index of the line to set
+ * @param line text to set
+ * @throws IndexOutOfBoundsException thrown when the provided index is {@literal > 3
+ * or < 0}
+ */
+ public void line(int index, net.kyori.adventure.text.@Nullable Component line) throws IndexOutOfBoundsException {
+ this.adventure$lines.set(index, line);
+ }
+ // Paper end
+
/**
* Gets all of the lines of text from the sign involved in this event.
*
* @return the String array for the sign's lines new text
+ * @deprecated in favour of {@link #lines()}
*/
@NotNull
+ @Deprecated // Paper
public String[] getLines() {
- return lines;
+ return adventure$lines.stream().map(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection()::serialize).toArray(String[]::new); // Paper
}
/**
@@ -60,10 +118,12 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
* provided index
* @throws IndexOutOfBoundsException thrown when the provided index is {@literal > 3
* or < 0}
+ * @deprecated in favour of {@link #line(int)}
*/
@Nullable
+ @Deprecated // Paper
public String getLine(int index) throws IndexOutOfBoundsException {
- return lines[index];
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.adventure$lines.get(index)); // Paper
}
/**
@@ -73,9 +133,11 @@ public class SignChangeEvent extends BlockEvent implements Cancellable {
* @param line text to set
* @throws IndexOutOfBoundsException thrown when the provided index is {@literal > 3
* or < 0}
+ * @deprecated in favour of {@link #line(int, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setLine(int index, @Nullable String line) throws IndexOutOfBoundsException {
- lines[index] = line;
+ adventure$lines.set(index, line != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line) : null); // Paper
}
/**
diff --git a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
index 3c2ea8fec3a748cab7f5ad9100d12bd8213ec6c9..03b4e0300d228e3f3a9f4f75c96e0cf9ed1a7d2d 100644
--- a/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
+++ b/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java
@@ -11,26 +11,49 @@ import org.jetbrains.annotations.Nullable;
*/
public class PlayerDeathEvent extends EntityDeathEvent {
private int newExp = 0;
- private String deathMessage = "";
+ private net.kyori.adventure.text.Component deathMessage; // Paper - adventure
private int newLevel = 0;
private int newTotalExp = 0;
private boolean keepLevel = false;
private boolean keepInventory = false;
+ // Paper start - adventure
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
+ this(player, drops, droppedExp, 0, deathMessage);
+ }
+
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final @Nullable net.kyori.adventure.text.Component deathMessage) {
+ this(player, drops, droppedExp, newExp, 0, 0, deathMessage);
+ }
+
+ @org.jetbrains.annotations.ApiStatus.Internal
+ public PlayerDeathEvent(final @NotNull Player player, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable net.kyori.adventure.text.Component deathMessage) {
+ super(player, drops, droppedExp);
+ this.newExp = newExp;
+ this.newTotalExp = newTotalExp;
+ this.newLevel = newLevel;
+ this.deathMessage = deathMessage;
+ }
+ // Paper end - adventure
+ @Deprecated // Paper
public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, @Nullable final String deathMessage) {
this(player, drops, droppedExp, 0, deathMessage);
}
+ @Deprecated // Paper
public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, @Nullable final String deathMessage) {
this(player, drops, droppedExp, newExp, 0, 0, deathMessage);
}
+ @Deprecated // Paper
public PlayerDeathEvent(@NotNull final Player player, @NotNull final List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, @Nullable final String deathMessage) {
super(player, drops, droppedExp);
this.newExp = newExp;
this.newTotalExp = newTotalExp;
this.newLevel = newLevel;
- this.deathMessage = deathMessage;
+ this.deathMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOrNull(deathMessage); // Paper
}
@NotNull
@@ -39,25 +62,49 @@ public class PlayerDeathEvent extends EntityDeathEvent {
return (Player) entity;
}
+ // Paper start - adventure
+ /**
+ * Set the death message that will appear to everyone on the server.
+ *
+ * @param deathMessage Component message to appear to other players on the server.
+ */
+ public void deathMessage(final net.kyori.adventure.text.@Nullable Component deathMessage) {
+ this.deathMessage = deathMessage;
+ }
+
+ /**
+ * Get the death message that will appear to everyone on the server.
+ *
+ * @return Component message to appear to other players on the server.
+ */
+ public net.kyori.adventure.text.@Nullable Component deathMessage() {
+ return this.deathMessage;
+ }
+ // Paper end - adventure
+
/**
* Set the death message that will appear to everyone on the server.
*
* @param deathMessage Message to appear to other players on the server.
+ * @deprecated in favour of {@link #deathMessage(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setDeathMessage(@Nullable String deathMessage) {
- this.deathMessage = deathMessage;
+ this.deathMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserializeOrNull(deathMessage); // Paper
}
/**
* Get the death message that will appear to everyone on the server.
*
* @return Message to appear to other players on the server.
+ * @deprecated in favour of {@link #deathMessage()}
*/
@Nullable
+ @Deprecated // Paper
public String getDeathMessage() {
- return deathMessage;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serializeOrNull(this.deathMessage); // Paper
}
-
+ // Paper end
/**
* Gets how much EXP the Player should have at respawn.
* <p>
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java
index a2e9bedc4d7c56f1ae6bd6ace2dff41537e41829..c3aeb1b622509ecd9e2230ce82e3bf07899fa540 100644
--- a/src/main/java/org/bukkit/event/inventory/InventoryType.java
+++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java
@@ -163,6 +163,18 @@ public enum InventoryType {
private final String title;
private final boolean isCreatable;
+ // Paper start
+ private final net.kyori.adventure.text.Component defaultTitleComponent;
+
+ /**
+ * Gets the inventory's default title.
+ *
+ * @return the inventory's default title
+ */
+ public net.kyori.adventure.text.@NotNull Component defaultTitle() {
+ return defaultTitleComponent;
+ }
+ // Paper end
private InventoryType(int defaultSize, /*@NotNull*/ String defaultTitle) {
this(defaultSize, defaultTitle, true);
}
@@ -171,6 +183,7 @@ public enum InventoryType {
size = defaultSize;
title = defaultTitle;
this.isCreatable = isCreatable;
+ this.defaultTitleComponent = net.kyori.adventure.text.Component.text(defaultTitle); // Paper - Adventure
}
public int getDefaultSize() {
@@ -178,6 +191,7 @@ public enum InventoryType {
}
@NotNull
+ @Deprecated // Paper
public String getDefaultTitle() {
return title;
}
diff --git a/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java b/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java
index 9c68c3f2d61500479f48b80264f625aaae2f3204..399afcd19fcb6acd24857ed6ab48cf0d105a01a3 100644
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java
@@ -22,7 +22,11 @@ import org.jetbrains.annotations.NotNull;
* <p>
* Care should be taken to check {@link #isAsynchronous()} and treat the event
* appropriately.
+ *
+ * @deprecated use {@link io.papermc.paper.event.player.AsyncChatEvent} instead
*/
+@Deprecated // Paper
+@org.bukkit.Warning(value = false, reason = "Don't nag on old event yet") // Paper
public class AsyncPlayerChatEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
diff --git a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
index 9866c07c999f46cb585709804aaad710c3031d5a..3432872303aa0df97b5d9090fe98b269ef3cb9f4 100644
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
@@ -10,11 +10,18 @@ import org.jetbrains.annotations.NotNull;
* Stores details for players attempting to log in.
* <p>
* This event is asynchronous, and not run using main thread.
+ * <p>
+ * When this event is fired, the player's locale is not
+ * available. Therefore, any translatable component will be
+ * rendered with the default locale, {@link java.util.Locale#US}.
+ * <p>
+ * Consider rendering any translatable yourself with {@link net.kyori.adventure.translation.GlobalTranslator#render}
+ * if the client's language is known.
*/
public class AsyncPlayerPreLoginEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Result result;
- private String message;
+ private net.kyori.adventure.text.Component message; // Paper
private final String name;
private final InetAddress ipAddress;
private final UUID uniqueId;
@@ -27,7 +34,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId) {
super(true);
this.result = Result.ALLOWED;
- this.message = "";
+ this.message = net.kyori.adventure.text.Component.empty(); // Paper
this.name = name;
this.ipAddress = ipAddress;
this.uniqueId = uniqueId;
@@ -79,6 +86,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
this.result = result == null ? null : Result.valueOf(result.name());
}
+ // Paper start
/**
* Gets the current kick message that will be used if getResult() !=
* Result.ALLOWED
@@ -86,7 +94,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
* @return Current kick message
*/
@NotNull
- public String getKickMessage() {
+ public net.kyori.adventure.text.Component kickMessage() {
return message;
}
@@ -95,16 +103,66 @@ public class AsyncPlayerPreLoginEvent extends Event {
*
* @param message New kick message
*/
- public void setKickMessage(@NotNull final String message) {
+ public void kickMessage(@NotNull final net.kyori.adventure.text.Component message) {
+ this.message = message;
+ }
+
+ /**
+ * Disallows the player from logging in, with the given reason
+ *
+ * @param result New result for disallowing the player
+ * @param message Kick message to display to the user
+ */
+ public void disallow(@NotNull final Result result, @NotNull final net.kyori.adventure.text.Component message) {
+ this.result = result;
this.message = message;
}
+ /**
+ * Disallows the player from logging in, with the given reason
+ *
+ * @param result New result for disallowing the player
+ * @param message Kick message to display to the user
+ * @deprecated This method uses a deprecated enum from {@link
+ * PlayerPreLoginEvent}
+ * @see #disallow(Result, String)
+ */
+ @Deprecated
+ public void disallow(@NotNull final PlayerPreLoginEvent.Result result, @NotNull final net.kyori.adventure.text.Component message) {
+ this.result = result == null ? null : Result.valueOf(result.name());
+ this.message = message;
+ }
+ // Paper end
+ /**
+ * Gets the current kick message that will be used if getResult() !=
+ * Result.ALLOWED
+ *
+ * @return Current kick message
+ * @deprecated in favour of {@link #kickMessage()}
+ */
+ @NotNull
+ @Deprecated // Paper
+ public String getKickMessage() {
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
+ }
+
+ /**
+ * Sets the kick message to display if getResult() != Result.ALLOWED
+ *
+ * @param message New kick message
+ * @deprecated in favour of {@link #kickMessage(net.kyori.adventure.text.Component)}
+ */
+ @Deprecated // Paper
+ public void setKickMessage(@NotNull final String message) {
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
+ }
+
/**
* Allows the player to log in
*/
public void allow() {
result = Result.ALLOWED;
- message = "";
+ message = net.kyori.adventure.text.Component.empty(); // Paper
}
/**
@@ -112,10 +170,12 @@ public class AsyncPlayerPreLoginEvent extends Event {
*
* @param result New result for disallowing the player
* @param message Kick message to display to the user
+ * @deprecated in favour of {@link #disallow(org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void disallow(@NotNull final Result result, @NotNull final String message) {
this.result = result;
- this.message = message;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
}
/**
@@ -130,7 +190,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
@Deprecated
public void disallow(@NotNull final PlayerPreLoginEvent.Result result, @NotNull final String message) {
this.result = result == null ? null : Result.valueOf(result.name());
- this.message = message;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
}
/**
diff --git a/src/main/java/org/bukkit/event/player/PlayerChatEvent.java b/src/main/java/org/bukkit/event/player/PlayerChatEvent.java
index a1f4261eaa1497554f1e51d1d5a072c2eb9226df..2c021bc2ff18f0b3af5feb9dafc8ccebd604f8b5 100644
--- a/src/main/java/org/bukkit/event/player/PlayerChatEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerChatEvent.java
@@ -12,12 +12,7 @@ import org.jetbrains.annotations.NotNull;
/**
* Holds information for player chat and commands
*
- * @deprecated This event will fire from the main thread and allows the use of
- * all of the Bukkit API, unlike the {@link AsyncPlayerChatEvent}.
- * <p>
- * Listening to this event forces chat to wait for the main thread which
- * causes delays for chat. {@link AsyncPlayerChatEvent} is the encouraged
- * alternative for thread safe implementations.
+ * @deprecated Listening to this event forces chat to wait for the main thread, delaying chat messages. It is recommended to use {@link io.papermc.paper.event.player.AsyncChatEvent} instead, wherever possible.
*/
@Deprecated
@Warning(reason = "Listening to this event forces chat to wait for the main thread, delaying chat messages.")
diff --git a/src/main/java/org/bukkit/event/player/PlayerEvent.java b/src/main/java/org/bukkit/event/player/PlayerEvent.java
index 793b661b6d2d05de3d7f4fc26a4c018a2af58e62..f6d3b817de3001f04ea4554c7c39a1290af3fd6d 100644
--- a/src/main/java/org/bukkit/event/player/PlayerEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerEvent.java
@@ -14,7 +14,7 @@ public abstract class PlayerEvent extends Event {
player = who;
}
- PlayerEvent(@NotNull final Player who, boolean async) {
+ public PlayerEvent(@NotNull final Player who, boolean async) { // Paper - public
super(async);
player = who;
diff --git a/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java b/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java
index d06684aba7688ce06777dbd837a46856a9d7767f..3e1e7cd0415509da4dd887db59efa55011b1dab4 100644
--- a/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java
@@ -10,30 +10,60 @@ import org.jetbrains.annotations.Nullable;
*/
public class PlayerJoinEvent extends PlayerEvent {
private static final HandlerList handlers = new HandlerList();
- private String joinMessage;
+ // Paper start
+ private net.kyori.adventure.text.Component joinMessage;
+ public PlayerJoinEvent(@NotNull final Player playerJoined, @Nullable final net.kyori.adventure.text.Component joinMessage) {
+ super(playerJoined);
+ this.joinMessage = joinMessage;
+ }
+ @Deprecated // 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
+ }
+
+ // Paper start
+ /**
+ * Gets the join message to send to all online players
+ *
+ * @return string join message. Can be null
+ */
+ public net.kyori.adventure.text.@Nullable Component joinMessage() {
+ return this.joinMessage;
+ }
+
+ /**
+ * Sets the join message to send to all online players
+ *
+ * @param joinMessage join message. If null, no message will be sent
+ */
+ public void joinMessage(net.kyori.adventure.text.@Nullable Component joinMessage) {
this.joinMessage = joinMessage;
}
+ // Paper end
/**
* Gets the join message to send to all online players
*
* @return string join message. Can be null
+ * @deprecated in favour of {@link #joinMessage()}
*/
@Nullable
+ @Deprecated // Paper
public String getJoinMessage() {
- return joinMessage;
+ return this.joinMessage == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.joinMessage); // Paper
}
/**
* Sets the join message to send to all online players
*
* @param joinMessage join message. If null, no message will be sent
+ * @deprecated in favour of {@link #joinMessage(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setJoinMessage(@Nullable String joinMessage) {
- this.joinMessage = joinMessage;
+ this.joinMessage = joinMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(joinMessage) : null; // Paper
}
@NotNull
diff --git a/src/main/java/org/bukkit/event/player/PlayerKickEvent.java b/src/main/java/org/bukkit/event/player/PlayerKickEvent.java
index 2f6ca42330675733b2b4132cbb66e433788d05d5..997b06c19a5277656521e0e298f2958c209f1da1 100644
--- a/src/main/java/org/bukkit/event/player/PlayerKickEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerKickEvent.java
@@ -10,35 +10,84 @@ import org.jetbrains.annotations.NotNull;
*/
public class PlayerKickEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
- private String leaveMessage;
- private String kickReason;
+ private net.kyori.adventure.text.Component leaveMessage; // Paper
+ private net.kyori.adventure.text.Component kickReason; // Paper
private boolean cancel;
+ @Deprecated // Paper
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
+ this.leaveMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(leaveMessage); // Paper
+ this.cancel = false;
+ }
+ // Paper start
+ 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;
this.leaveMessage = leaveMessage;
this.cancel = false;
}
+ /**
+ * Gets the leave message send to all online players
+ *
+ * @return string kick reason
+ */
+ public net.kyori.adventure.text.@NotNull Component leaveMessage() {
+ return this.leaveMessage;
+ }
+
+ /**
+ * Sets the leave message send to all online players
+ *
+ * @param leaveMessage leave message
+ */
+ public void leaveMessage(net.kyori.adventure.text.@NotNull Component leaveMessage) {
+ this.leaveMessage = leaveMessage;
+ }
+
/**
* Gets the reason why the player is getting kicked
*
* @return string kick reason
*/
+ public net.kyori.adventure.text.@NotNull Component reason() {
+ return this.kickReason;
+ }
+
+ /**
+ * Sets the reason why the player is getting kicked
+ *
+ * @param kickReason kick reason
+ */
+ public void reason(net.kyori.adventure.text.@NotNull Component kickReason) {
+ this.kickReason = kickReason;
+ }
+ // Paper end
+
+ /**
+ * Gets the reason why the player is getting kicked
+ *
+ * @return string kick reason
+ * @deprecated in favour of {@link #reason()}
+ */
@NotNull
+ @Deprecated // Paper
public String getReason() {
- return kickReason;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.kickReason); // Paper
}
/**
* Gets the leave message send to all online players
*
* @return string kick reason
+ * @deprecated in favour of {@link #leaveMessage()}
*/
@NotNull
+ @Deprecated // Paper
public String getLeaveMessage() {
- return leaveMessage;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.leaveMessage); // Paper
}
@Override
@@ -55,18 +104,22 @@ public class PlayerKickEvent extends PlayerEvent implements Cancellable {
* Sets the reason why the player is getting kicked
*
* @param kickReason kick reason
+ * @deprecated in favour of {@link #reason(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setReason(@NotNull String kickReason) {
- this.kickReason = kickReason;
+ this.kickReason = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(kickReason); // Paper
}
/**
* Sets the leave message send to all online players
*
* @param leaveMessage leave message
+ * @deprecated in favour of {@link #leaveMessage(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setLeaveMessage(@NotNull String leaveMessage) {
- this.leaveMessage = leaveMessage;
+ this.leaveMessage = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(leaveMessage); // Paper
}
@NotNull
diff --git a/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java b/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java
index 36b436e145a7215682b692a87ab894df25752c1d..c5e8bffef736365881953161ff812c98adf93a80 100644
--- a/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java
@@ -12,17 +12,31 @@ public class PlayerLocaleChangeEvent extends PlayerEvent {
private static final HandlerList handlers = new HandlerList();
//
private final String locale;
+ // Paper start
+ private final java.util.Locale adventure$locale;
+ /**
+ * @see Player#locale()
+ *
+ * @return the player's new locale
+ */
+ public @NotNull java.util.Locale locale() {
+ return this.adventure$locale;
+ }
+ // Paper end
public PlayerLocaleChangeEvent(@NotNull Player who, @NotNull String locale) {
super(who);
this.locale = locale;
+ this.adventure$locale = net.kyori.adventure.translation.Translator.parseLocale(locale); // Paper
}
/**
* @return the player's new locale
* @see Player#getLocale()
+ * @deprecated in favour of {@link #locale()}
*/
@NotNull
+ @Deprecated // Paper
public String getLocale() {
return locale;
}
diff --git a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
index 2bc81b0aa73f7f5b0352121f6bf18fa63acf7a83..eaa0548cf430bf5b58ff84e0a4403c451699db28 100644
--- a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java
@@ -18,7 +18,7 @@ public class PlayerLoginEvent extends PlayerEvent {
private final InetAddress realAddress;
private final String hostname;
private Result result = Result.ALLOWED;
- private String message = "";
+ private net.kyori.adventure.text.Component message = net.kyori.adventure.text.Component.empty();
/**
* This constructor defaults message to an empty string, and result to
@@ -60,13 +60,53 @@ public class PlayerLoginEvent extends PlayerEvent {
* @param result The result status for this event
* @param message The message to be displayed if result denies login
* @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
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;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
+ }
+
+ // Paper start
+ /**
+ * This constructor pre-configures the event with a result and message
+ *
+ * @param player The {@link Player} for this event
+ * @param hostname The hostname that was used to connect to the server
+ * @param address The address the player used to connect, provided for
+ * timing issues
+ * @param result The result status for this event
+ * @param message The message to be displayed if result denies login
+ * @param realAddress the actual, unspoofed connecting address
+ */
+ 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;
this.message = message;
}
+ /**
+ * Gets the current kick message that will be used if getResult() !=
+ * Result.ALLOWED
+ *
+ * @return Current kick message
+ */
+ public net.kyori.adventure.text.@NotNull Component kickMessage() {
+ return this.message;
+ }
+
+ /**
+ * Sets the kick message to display if getResult() != Result.ALLOWED
+ *
+ * @param message New kick message
+ */
+ public void kickMessage(net.kyori.adventure.text.@NotNull Component message) {
+ this.message = message;
+ }
+ // Paper end
+
/**
* Gets the current result of the login, as an enum
*
@@ -91,19 +131,23 @@ public class PlayerLoginEvent extends PlayerEvent {
* Result.ALLOWED
*
* @return Current kick message
+ * @deprecated in favour of {@link #kickMessage()}
*/
@NotNull
+ @Deprecated // Paper
public String getKickMessage() {
- return message;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
}
/**
* Sets the kick message to display if getResult() != Result.ALLOWED
*
* @param message New kick message
+ * @deprecated in favour of {@link #kickMessage(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setKickMessage(@NotNull final String message) {
- this.message = message;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
}
/**
@@ -122,7 +166,7 @@ public class PlayerLoginEvent extends PlayerEvent {
*/
public void allow() {
result = Result.ALLOWED;
- message = "";
+ message = net.kyori.adventure.text.Component.empty(); // Paper
}
/**
@@ -130,8 +174,21 @@ public class PlayerLoginEvent extends PlayerEvent {
*
* @param result New result for disallowing the player
* @param message Kick message to display to the user
+ * @deprecated in favour of {@link #disallow(Result, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper start
public void disallow(@NotNull final Result result, @NotNull final String message) {
+ this.result = result;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message);
+ }
+ /**
+ * Disallows the player from logging in, with the given reason
+ *
+ * @param result New result for disallowing the player
+ * @param message Kick message to display to the user
+ */
+ public void disallow(@NotNull final Result result, @NotNull final net.kyori.adventure.text.Component message) {
+ // Paper end
this.result = result;
this.message = message;
}
diff --git a/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
index fb066251f793ec3b41bfc075b9478901b15ee549..175ed12dd1698f4d153c9acdac8340c15a427ea5 100644
--- a/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
@@ -9,6 +9,13 @@ import org.jetbrains.annotations.NotNull;
/**
* Stores details for players attempting to log in
+ * <p>
+ * When this event is fired, the player's locale is not
+ * available. Therefore, any translatable component will be
+ * rendered with the default locale, {@link java.util.Locale#US}.
+ * <p>
+ * Consider rendering any translatable yourself with {@link net.kyori.adventure.translation.GlobalTranslator#render}
+ * if the client's language is known.
*
* @deprecated This event causes synchronization from the login thread; {@link
* AsyncPlayerPreLoginEvent} is preferred to keep the secondary threads
@@ -19,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
public class PlayerPreLoginEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Result result;
- private String message;
+ private net.kyori.adventure.text.Component message; // Paper
private final String name;
private final InetAddress ipAddress;
private final UUID uniqueId;
@@ -31,7 +38,7 @@ public class PlayerPreLoginEvent extends Event {
public PlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId) {
this.result = Result.ALLOWED;
- this.message = "";
+ this.message = net.kyori.adventure.text.Component.empty(); // Paper
this.name = name;
this.ipAddress = ipAddress;
this.uniqueId = uniqueId;
@@ -56,6 +63,7 @@ public class PlayerPreLoginEvent extends Event {
this.result = result;
}
+ // Paper start
/**
* Gets the current kick message that will be used if getResult() !=
* Result.ALLOWED
@@ -63,7 +71,7 @@ public class PlayerPreLoginEvent extends Event {
* @return Current kick message
*/
@NotNull
- public String getKickMessage() {
+ public net.kyori.adventure.text.Component kickMessage() {
return message;
}
@@ -72,16 +80,51 @@ public class PlayerPreLoginEvent extends Event {
*
* @param message New kick message
*/
- public void setKickMessage(@NotNull final String message) {
+ public void kickMessage(@NotNull final net.kyori.adventure.text.Component message) {
this.message = message;
}
+ /**
+ * Disallows the player from logging in, with the given reason
+ *
+ * @param result New result for disallowing the player
+ * @param message Kick message to display to the user
+ */
+ public void disallow(@NotNull final Result result, @NotNull final net.kyori.adventure.text.Component message) {
+ this.result = result;
+ this.message = message;
+ }
+ // Paper end
+ /**
+ * Gets the current kick message that will be used if getResult() !=
+ * Result.ALLOWED
+ *
+ * @return Current kick message
+ * @deprecated in favour of {@link #kickMessage()}
+ */
+ @Deprecated // Paper
+ @NotNull
+ public String getKickMessage() {
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
+ }
+
+ /**
+ * Sets the kick message to display if getResult() != Result.ALLOWED
+ *
+ * @param message New kick message
+ * @deprecated in favour of {@link #kickMessage(net.kyori.adventure.text.Component)}
+ */
+ @Deprecated // Paper
+ public void setKickMessage(@NotNull final String message) {
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
+ }
+
/**
* Allows the player to log in
*/
public void allow() {
result = Result.ALLOWED;
- message = "";
+ message = net.kyori.adventure.text.Component.empty(); // Paper
}
/**
@@ -89,10 +132,12 @@ public class PlayerPreLoginEvent extends Event {
*
* @param result New result for disallowing the player
* @param message Kick message to display to the user
+ * @deprecated in favour of {@link #disallow(org.bukkit.event.player.PlayerPreLoginEvent.Result, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void disallow(@NotNull final Result result, @NotNull final String message) {
this.result = result;
- this.message = message;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
}
/**
diff --git a/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java b/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java
index d70c25f404e994766a9ebce89a917c8d0719777c..14b27eaaf744736b3e56bb1383481df98a218c43 100644
--- a/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java
+++ b/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java
@@ -10,30 +10,59 @@ import org.jetbrains.annotations.Nullable;
*/
public class PlayerQuitEvent extends PlayerEvent {
private static final HandlerList handlers = new HandlerList();
- private String quitMessage;
+ private net.kyori.adventure.text.Component quitMessage; // Paper
+ @Deprecated // Paper
public PlayerQuitEvent(@NotNull final Player who, @Nullable final String quitMessage) {
super(who);
+ this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper
+ }
+ // Paper start
+ public PlayerQuitEvent(@NotNull final Player who, @Nullable final net.kyori.adventure.text.Component quitMessage) {
+ super(who);
+ this.quitMessage = quitMessage;
+ }
+
+ /**
+ * Gets the quit message to send to all online players
+ *
+ * @return string quit message
+ */
+ public net.kyori.adventure.text.@Nullable Component quitMessage() {
+ return quitMessage;
+ }
+
+ /**
+ * Sets the quit message to send to all online players
+ *
+ * @param quitMessage quit message
+ */
+ public void quitMessage(net.kyori.adventure.text.@Nullable Component quitMessage) {
this.quitMessage = quitMessage;
}
+ // Paper end
/**
* Gets the quit message to send to all online players
*
* @return string quit message
+ * @deprecated in favour of {@link #quitMessage()}
*/
@Nullable
+ @Deprecated // Paper
public String getQuitMessage() {
- return quitMessage;
+ return this.quitMessage == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.quitMessage); // Paper
}
/**
* Sets the quit message to send to all online players
*
* @param quitMessage quit message
+ * @deprecated in favour of {@link #quitMessage(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setQuitMessage(@Nullable String quitMessage) {
- this.quitMessage = quitMessage;
+ this.quitMessage = quitMessage != null ? net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(quitMessage) : null; // Paper
}
@NotNull
diff --git a/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java b/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java
index 03bfca9d368bbe4b7c1353d52c883e756bf69bda..25c0fe98489d903fdf77cbdd181c95593bd7f727 100644
--- a/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java
+++ b/src/main/java/org/bukkit/event/server/BroadcastMessageEvent.java
@@ -9,16 +9,16 @@ import org.jetbrains.annotations.NotNull;
/**
* Event triggered for server broadcast messages such as from
- * {@link org.bukkit.Server#broadcast(String, String)}.
+ * {@link org.bukkit.Server#broadcast(net.kyori.adventure.text.Component)} (String, String)}.
*
- * <b>This event behaves similarly to {@link AsyncPlayerChatEvent} in that it
+ * <b>This event behaves similarly to {@link io.papermc.paper.event.player.AsyncChatEvent} in that it
* should be async if fired from an async thread. Please see that event for
* further information.</b>
*/
public class BroadcastMessageEvent extends ServerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
- private String message;
+ private net.kyori.adventure.text.Component message; // Paper
private final Set<CommandSender> recipients;
private boolean cancelled = false;
@@ -27,29 +27,66 @@ public class BroadcastMessageEvent extends ServerEvent implements Cancellable {
this(false, message, recipients);
}
+ @Deprecated // Paper
public BroadcastMessageEvent(boolean isAsync, @NotNull String message, @NotNull Set<CommandSender> recipients) {
+ // Paper start
+ super(isAsync);
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message);
+ this.recipients = recipients;
+ }
+
+ @Deprecated
+ public BroadcastMessageEvent(net.kyori.adventure.text.@NotNull Component message, @NotNull Set<CommandSender> recipients) {
+ this(false, message, recipients);
+ }
+
+ public BroadcastMessageEvent(boolean isAsync, net.kyori.adventure.text.@NotNull Component message, @NotNull Set<CommandSender> recipients) {
+ // Paper end
super(isAsync);
this.message = message;
this.recipients = recipients;
}
+ // Paper start
+ /**
+ * Get the broadcast message.
+ *
+ * @return Message to broadcast
+ */
+ public net.kyori.adventure.text.@NotNull Component message() {
+ return this.message;
+ }
+
+ /**
+ * Set the broadcast message.
+ *
+ * @param message New message to broadcast
+ */
+ public void message(net.kyori.adventure.text.@NotNull Component message) {
+ this.message = message;
+ }
+ // Paper end
/**
* Get the message to broadcast.
*
* @return Message to broadcast
+ * @deprecated in favour of {@link #message()}
*/
@NotNull
+ @Deprecated // Paper
public String getMessage() {
- return message;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.message); // Paper
}
/**
* Set the message to broadcast.
*
* @param message New message to broadcast
+ * @deprecated in favour of {@link #message(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setMessage(@NotNull String message) {
- this.message = message;
+ this.message = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(message); // Paper
}
/**
diff --git a/src/main/java/org/bukkit/event/server/ServerListPingEvent.java b/src/main/java/org/bukkit/event/server/ServerListPingEvent.java
index 5adbe0514129abf3cfbc4b29a213f522359fe2e1..72ebc29db42d08d1d0361dba462fc8a573fbf918 100644
--- a/src/main/java/org/bukkit/event/server/ServerListPingEvent.java
+++ b/src/main/java/org/bukkit/event/server/ServerListPingEvent.java
@@ -22,7 +22,7 @@ public class ServerListPingEvent extends ServerEvent implements Iterable<Player>
private static final HandlerList handlers = new HandlerList();
private final String hostname;
private final InetAddress address;
- private String motd;
+ private net.kyori.adventure.text.Component motd; // Paper
private final int numPlayers;
private int maxPlayers;
@@ -31,7 +31,7 @@ public class ServerListPingEvent extends ServerEvent implements Iterable<Player>
Preconditions.checkArgument(numPlayers >= 0, "Cannot have negative number of players online", numPlayers);
this.hostname = hostname;
this.address = address;
- this.motd = motd;
+ this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper
this.numPlayers = numPlayers;
this.maxPlayers = maxPlayers;
}
@@ -45,15 +45,80 @@ public class ServerListPingEvent extends ServerEvent implements Iterable<Player>
* @param address the address of the pinger
* @param motd the message of the day
* @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
protected ServerListPingEvent(@NotNull final String hostname, @NotNull final InetAddress address, @NotNull final String motd, final int maxPlayers) {
super(true);
this.numPlayers = MAGIC_PLAYER_COUNT;
this.hostname = hostname;
this.address = address;
+ this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper
+ this.maxPlayers = maxPlayers;
+ }
+ // Paper start
+ @Deprecated
+ 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);
+ }
+ 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);
+ this.hostname = hostname;
+ this.address = address;
this.motd = motd;
+ this.numPlayers = numPlayers;
this.maxPlayers = maxPlayers;
}
+ /**
+ * This constructor is intended for implementations that provide the
+ * {@link #iterator()} method, thus provided the {@link #getNumPlayers()}
+ * count.
+ *
+ * @param address the address of the pinger
+ * @param motd the message of the day
+ * @param maxPlayers the max number of players
+ * @deprecated in favour of {@link #ServerListPingEvent(String, java.net.InetAddress, net.kyori.adventure.text.Component, int)}
+ */
+ @Deprecated
+ protected ServerListPingEvent(@NotNull final InetAddress address, @NotNull final net.kyori.adventure.text.Component motd, final int maxPlayers) {
+ this("", address, motd, maxPlayers);
+ }
+
+ /**
+ * This constructor is intended for implementations that provide the
+ * {@link #iterator()} method, thus provided the {@link #getNumPlayers()}
+ * count.
+ *
+ * @param hostname The hostname that was used to connect to the server
+ * @param address the address of the pinger
+ * @param motd the message of the day
+ * @param maxPlayers the max number of players
+ */
+ 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;
+ this.address = address;
+ this.motd = motd;
+ this.maxPlayers = maxPlayers;
+ }
+ /**
+ * Get the message of the day message.
+ *
+ * @return the message of the day
+ */
+ public net.kyori.adventure.text.@NotNull Component motd() {
+ return motd;
+ }
+ /**
+ * Change the message of the day message.
+ *
+ * @param motd the message of the day
+ */
+ 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
@@ -80,19 +145,23 @@ public class ServerListPingEvent extends ServerEvent implements Iterable<Player>
* Get the message of the day message.
*
* @return the message of the day
+ * @deprecated in favour of {@link #motd()}
*/
@NotNull
+ @Deprecated // Paper
public String getMotd() {
- return motd;
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.motd); // Paper
}
/**
* Change the message of the day message.
*
* @param motd the message of the day
+ * @deprecated in favour of {@link #motd(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setMotd(@NotNull String motd) {
- this.motd = motd;
+ this.motd = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(motd); // Paper
}
/**
diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java
index e12996492c1558fed9fab30de9f8018e0ed7fac3..002acfbdce1db10f7ba1b6a013e678f504ac6e69 100644
--- a/src/main/java/org/bukkit/inventory/InventoryView.java
+++ b/src/main/java/org/bukkit/inventory/InventoryView.java
@@ -447,12 +447,26 @@ public abstract class InventoryView {
return getPlayer().setWindowProperty(prop, value);
}
+ // Paper start
/**
* Get the title of this inventory window.
*
* @return The title.
*/
@NotNull
+ public /*abstract*/ net.kyori.adventure.text.Component title() {
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.getTitle());
+ }
+ // Paper end
+
+ /**
+ * Get the title of this inventory window.
+ *
+ * @return The title.
+ * @deprecated in favour of {@link #title()}
+ */
+ @Deprecated // Paper
+ @NotNull
public abstract String getTitle();
/**
diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java
index e606f63a284db71663aee667597447b875e20627..6b1c55249b39a45c33ac49bacef4e9d80ba8cc3a 100644
--- a/src/main/java/org/bukkit/inventory/ItemFactory.java
+++ b/src/main/java/org/bukkit/inventory/ItemFactory.java
@@ -217,4 +217,24 @@ public interface ItemFactory {
*/
@NotNull
ItemStack enchantItem(@NotNull final ItemStack item, final int level, final boolean allowTreasures);
+
+ // Paper start - Adventure
+ /**
+ * Creates a hover event for the given item.
+ *
+ * @param item The item
+ * @return A hover event
+ */
+ @NotNull
+ net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowItem> asHoverEvent(final @NotNull ItemStack item, final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowItem> op);
+
+ /**
+ * Get the formatted display name of the {@link ItemStack}.
+ *
+ * @param itemStack the {@link ItemStack}
+ * @return display name of the {@link ItemStack}
+ */
+ @NotNull
+ net.kyori.adventure.text.Component displayName(@NotNull ItemStack itemStack);
+ // Paper end - Adventure
}
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
index d80b0a52968920b990a75cff85e436a16d782500..9d327f0832c40d4a8d212346284274f6cf78834f 100644
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
* use this class to encapsulate Materials for which {@link Material#isItem()}
* returns false.</b>
*/
-public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable {
+public class ItemStack implements Cloneable, ConfigurationSerializable, Translatable, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowItem> { // Paper
private Material type = Material.AIR;
private int amount = 0;
private MaterialData data = null;
@@ -602,4 +602,21 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
public String getTranslationKey() {
return Bukkit.getUnsafe().getTranslationKey(this);
}
+
+ // Paper start
+ @NotNull
+ @Override
+ public net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowItem> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowItem> op) {
+ return org.bukkit.Bukkit.getServer().getItemFactory().asHoverEvent(this, op);
+ }
+
+ /**
+ * Get the formatted display name of the {@link ItemStack}.
+ *
+ * @return display name of the {@link ItemStack}
+ */
+ public net.kyori.adventure.text.@NotNull Component displayName() {
+ return Bukkit.getServer().getItemFactory().displayName(this);
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/inventory/meta/BookMeta.java b/src/main/java/org/bukkit/inventory/meta/BookMeta.java
index 94852d50e88d0594b84b581cd627174043629995..be7c2cfc757e4dd15927be850739d401958fb227 100644
--- a/src/main/java/org/bukkit/inventory/meta/BookMeta.java
+++ b/src/main/java/org/bukkit/inventory/meta/BookMeta.java
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
* Represents a book ({@link Material#WRITABLE_BOOK} or {@link
* Material#WRITTEN_BOOK}) that can have a title, an author, and pages.
*/
-public interface BookMeta extends ItemMeta {
+public interface BookMeta extends ItemMeta, net.kyori.adventure.inventory.Book { // Paper
/**
* Represents the generation (or level of copying) of a written book
@@ -119,6 +119,109 @@ public interface BookMeta extends ItemMeta {
*/
boolean hasPages();
+ // Paper start
+ /**
+ * Gets the title of the book.
+ * <p>
+ * Plugins should check that hasTitle() returns true before calling this
+ * method.
+ *
+ * @return the title of the book
+ */
+ @Override
+ net.kyori.adventure.text.@Nullable Component title();
+
+ /**
+ * Sets the title of the book.
+ * <p>
+ * Limited to 32 characters. Removes title when given null.
+ *
+ * @param title the title to set
+ * @return the same {@link BookMeta} instance
+ */
+ @org.jetbrains.annotations.Contract(value = "_ -> this", pure = false)
+ @Override
+ @NotNull BookMeta title(net.kyori.adventure.text.@Nullable Component title);
+
+ /**
+ * Gets the author of the book.
+ * <p>
+ * Plugins should check that hasAuthor() returns true before calling this
+ * method.
+ *
+ * @return the author of the book
+ */
+ @Override
+ net.kyori.adventure.text.@Nullable Component author();
+
+ /**
+ * Sets the author of the book. Removes author when given null.
+ *
+ * @param author the author to set
+ * @return the same {@link BookMeta} instance
+ */
+ @org.jetbrains.annotations.Contract(value = "_ -> this", pure = false)
+ @Override
+ @NotNull BookMeta author(net.kyori.adventure.text.@Nullable Component author);
+
+ /**
+ * Gets the specified page in the book. The page must exist.
+ * <p>
+ * Pages are 1-indexed.
+ *
+ * @param page the page number to get, in range [1, getPageCount()]
+ * @return the page from the book
+ */
+ net.kyori.adventure.text.@NotNull Component page(int page);
+
+ /**
+ * Sets the specified page in the book. Pages of the book must be
+ * contiguous.
+ * <p>
+ * The data can be up to 256 characters in length, additional characters
+ * are truncated.
+ * <p>
+ * Pages are 1-indexed.
+ *
+ * @param page the page number to set, in range [1, getPageCount()]
+ * @param data the data to set for that page
+ */
+ void page(int page, net.kyori.adventure.text.@NotNull Component data);
+
+ /**
+ * Adds new pages to the end of the book. Up to a maximum of 50 pages with
+ * 256 characters per page.
+ *
+ * @param pages A list of strings, each being a page
+ */
+ void addPages(net.kyori.adventure.text.@NotNull Component @NotNull ... pages);
+
+ interface BookMetaBuilder extends Builder {
+
+ @Override
+ @NotNull BookMetaBuilder title(net.kyori.adventure.text.@Nullable Component title);
+
+ @Override
+ @NotNull BookMetaBuilder author(net.kyori.adventure.text.@Nullable Component author);
+
+ @Override
+ @NotNull BookMetaBuilder addPage(net.kyori.adventure.text.@NotNull Component page);
+
+ @Override
+ @NotNull BookMetaBuilder pages(net.kyori.adventure.text.@NotNull Component @NotNull ... pages);
+
+ @Override
+ @NotNull BookMetaBuilder pages(java.util.@NotNull Collection<net.kyori.adventure.text.Component> pages);
+
+ @Override
+ @NotNull BookMeta build();
+ }
+
+ @Override
+ @NotNull BookMetaBuilder toBuilder();
+
+ // Paper end
+
/**
* Gets the specified page in the book. The given page must exist.
* <p>
@@ -126,8 +229,10 @@ public interface BookMeta extends ItemMeta {
*
* @param page the page number to get, in range [1, getPageCount()]
* @return the page from the book
+ * @deprecated in favour of {@link #page(int)}
*/
@NotNull
+ @Deprecated // Paper
String getPage(int page);
/**
@@ -141,15 +246,19 @@ public interface BookMeta extends ItemMeta {
*
* @param page the page number to set, in range [1, getPageCount()]
* @param data the data to set for that page
+ * @deprecated in favour of {@link #page(int, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setPage(int page, @NotNull String data);
/**
* Gets all the pages in the book.
*
* @return list of all the pages in the book
+ * @deprecated in favour of {@link #pages()}
*/
@NotNull
+ @Deprecated // Paper
List<String> getPages();
/**
@@ -157,7 +266,9 @@ public interface BookMeta extends ItemMeta {
* pages. Maximum 100 pages with 256 characters per page.
*
* @param pages A list of pages to set the book to use
+ * @deprecated in favour of {@link #pages(List)}
*/
+ @Deprecated // Paper
void setPages(@NotNull List<String> pages);
/**
@@ -165,7 +276,9 @@ public interface BookMeta extends ItemMeta {
* pages. Maximum 50 pages with 256 characters per page.
*
* @param pages A list of strings, each being a page
+ * @deprecated in favour of {@link #pages(net.kyori.adventure.text.Component...)}
*/
+ @Deprecated // Paper
void setPages(@NotNull String... pages);
/**
@@ -173,7 +286,9 @@ public interface BookMeta extends ItemMeta {
* 256 characters per page.
*
* @param pages A list of strings, each being a page
+ * @deprecated in favour of {@link #addPages(net.kyori.adventure.text.Component...)}
*/
+ @Deprecated // Paper
void addPage(@NotNull String... pages);
/**
@@ -195,8 +310,10 @@ public interface BookMeta extends ItemMeta {
*
* @param page the page number to get
* @return the page from the book
+ * @deprecated in favour of {@link #page(int)}
*/
@NotNull
+ @Deprecated // Paper
public BaseComponent[] getPage(int page) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -210,7 +327,9 @@ public interface BookMeta extends ItemMeta {
*
* @param page the page number to set
* @param data the data to set for that page
+ * @deprecated in favour of {@link #page(int, net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setPage(int page, @Nullable BaseComponent... data) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -219,8 +338,10 @@ public interface BookMeta extends ItemMeta {
* Gets all the pages in the book.
*
* @return list of all the pages in the book
+ * @deprecated in favour of {@link #pages()}
*/
@NotNull
+ @Deprecated // Paper
public List<BaseComponent[]> getPages() {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -230,7 +351,9 @@ public interface BookMeta extends ItemMeta {
* pages. Maximum 50 pages with 256 characters per page.
*
* @param pages A list of pages to set the book to use
+ * @deprecated in favour of {@link #pages(java.util.List)}
*/
+ @Deprecated // Paper
public void setPages(@NotNull List<BaseComponent[]> pages) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -240,7 +363,9 @@ public interface BookMeta extends ItemMeta {
* pages. Maximum 50 pages with 256 characters per page.
*
* @param pages A list of component arrays, each being a page
+ * @deprecated in favour of {@link #pages(net.kyori.adventure.text.Component...)}
*/
+ @Deprecated // Paper
public void setPages(@NotNull BaseComponent[]... pages) {
throw new UnsupportedOperationException("Not supported yet.");
}
@@ -250,7 +375,9 @@ public interface BookMeta extends ItemMeta {
* with 256 characters per page.
*
* @param pages A list of component arrays, each being a page
+ * @deprecated in favour of {@link #addPages(net.kyori.adventure.text.Component...)}
*/
+ @Deprecated // Paper
public void addPage(@NotNull BaseComponent[]... pages) {
throw new UnsupportedOperationException("Not supported yet.");
}
diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
index 8ca9605fc1193de9277407f02f755d81190472a4..d7fab2b856f6dfec4f9225c1bdb4254b238d98a4 100644
--- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
+++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
@@ -32,6 +32,24 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
*/
boolean hasDisplayName();
+ // Paper start
+ /**
+ * Gets the display name.
+ *
+ * <p>Plugins should check that {@link #hasDisplayName()} returns <code>true</code> before calling this method.</p>
+ *
+ * @return the display name
+ */
+ net.kyori.adventure.text.@Nullable Component displayName();
+
+ /**
+ * Sets the display name.
+ *
+ * @param displayName the display name to set
+ */
+ void displayName(final net.kyori.adventure.text.@Nullable Component displayName);
+ // Paper end
+
/**
* Gets the display name that is set.
* <p>
@@ -39,7 +57,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* before calling this method.
*
* @return the display name that is set
+ * @deprecated in favour of {@link #displayName()}
*/
+ @Deprecated // Paper
@NotNull
String getDisplayName();
@@ -47,7 +67,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Sets the display name.
*
* @param name the name to set
+ * @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setDisplayName(@Nullable String name);
/**
@@ -82,6 +104,24 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
*/
boolean hasLore();
+ // Paper start
+ /**
+ * Gets the lore.
+ *
+ * <p>Plugins should check that {@link #hasLore()} returns <code>true</code> before calling this method.</p>
+ *
+ * @return the lore
+ */
+ @Nullable List<net.kyori.adventure.text.Component> lore();
+
+ /**
+ * Sets the lore.
+ *
+ * @param lore the lore to set
+ */
+ void lore(final @Nullable List<? extends net.kyori.adventure.text.Component> lore);
+ // Paper end
+
/**
* Gets the lore that is set.
* <p>
@@ -89,7 +129,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* calling this method.
*
* @return a list of lore that is set
+ * @deprecated in favour of {@link #lore()}
*/
+ @Deprecated // Paper
@Nullable
List<String> getLore();
@@ -98,7 +140,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Removes lore when given null.
*
* @param lore the lore that will be set
+ * @deprecated in favour of {@link #lore(List)}
*/
+ @Deprecated // Paper
void setLore(@Nullable List<String> lore);
/**
diff --git a/src/main/java/org/bukkit/map/MapCursor.java b/src/main/java/org/bukkit/map/MapCursor.java
index b90fd819a781d3a2117ffa25f0864b1576901f9f..7d4f4970dae6fe4eeea6b6b6810dcecfe20d6e51 100644
--- a/src/main/java/org/bukkit/map/MapCursor.java
+++ b/src/main/java/org/bukkit/map/MapCursor.java
@@ -10,7 +10,7 @@ public final class MapCursor {
private byte x, y;
private byte direction, type;
private boolean visible;
- private String caption;
+ private net.kyori.adventure.text.Component caption; // Paper
/**
* Initialize the map cursor.
@@ -24,7 +24,7 @@ public final class MapCursor {
*/
@Deprecated
public MapCursor(byte x, byte y, byte direction, byte type, boolean visible) {
- this(x, y, direction, type, visible, null);
+ this(x, y, direction, type, visible, (String) null); // Paper
}
/**
@@ -37,7 +37,7 @@ public final class MapCursor {
* @param visible Whether the cursor is visible by default.
*/
public MapCursor(byte x, byte y, byte direction, @NotNull Type type, boolean visible) {
- this(x, y, direction, type, visible, null);
+ this(x, y, direction, type, visible, (String) null); // Paper
}
/**
@@ -49,7 +49,7 @@ public final class MapCursor {
* @param type The type (color/style) of the map cursor.
* @param visible Whether the cursor is visible by default.
* @param caption cursor caption
- * @deprecated Magic value
+ * @deprecated Magic value. Use {@link #MapCursor(byte, byte, byte, byte, boolean, net.kyori.adventure.text.Component)}
*/
@Deprecated
public MapCursor(byte x, byte y, byte direction, byte type, boolean visible, @Nullable String caption) {
@@ -58,8 +58,42 @@ public final class MapCursor {
setDirection(direction);
setRawType(type);
this.visible = visible;
- this.caption = caption;
+ this.caption = caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(caption); // Paper
}
+ // Paper start
+ /**
+ * Initialize the map cursor.
+ *
+ * @param x The x coordinate, from -128 to 127.
+ * @param y The y coordinate, from -128 to 127.
+ * @param direction The facing of the cursor, from 0 to 15.
+ * @param type The type (color/style) of the map cursor.
+ * @param visible Whether the cursor is visible by default.
+ * @param caption cursor caption
+ * @deprecated Magic value
+ */
+ @Deprecated
+ public MapCursor(byte x, byte y, byte direction, byte type, boolean visible, net.kyori.adventure.text.@Nullable Component caption) {
+ this.x = x; this.y = y; this.visible = visible; this.caption = caption;
+ setDirection(direction);
+ setRawType(type);
+ }
+ /**
+ * Initialize the map cursor.
+ *
+ * @param x The x coordinate, from -128 to 127.
+ * @param y The y coordinate, from -128 to 127.
+ * @param direction The facing of the cursor, from 0 to 15.
+ * @param type The type (color/style) of the map cursor.
+ * @param visible Whether the cursor is visible by default.
+ * @param caption cursor caption
+ */
+ public MapCursor(byte x, byte y, byte direction, @NotNull Type type, boolean visible, net.kyori.adventure.text.@Nullable Component caption) {
+ this.x = x; this.y = y; this.visible = visible; this.caption = caption;
+ setDirection(direction);
+ setType(type);
+ }
+ // Paper end
/**
* Initialize the map cursor.
@@ -77,7 +111,7 @@ public final class MapCursor {
setDirection(direction);
setType(type);
this.visible = visible;
- this.caption = caption;
+ this.caption = caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(caption); // Paper
}
/**
@@ -200,23 +234,45 @@ public final class MapCursor {
this.visible = visible;
}
+ // Paper start
+ /**
+ * Gets the caption on this cursor.
+ *
+ * @return caption
+ */
+ public net.kyori.adventure.text.@Nullable Component caption() {
+ return this.caption;
+ }
+ /**
+ * Sets the caption on this cursor.
+ *
+ * @param caption new caption
+ */
+ public void caption(net.kyori.adventure.text.@Nullable Component caption) {
+ this.caption = caption;
+ }
+ // Paper end
/**
* Gets the caption on this cursor.
*
* @return caption
+ * @deprecated in favour of {@link #caption()}
*/
@Nullable
+ @Deprecated // Paper
public String getCaption() {
- return caption;
+ return this.caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(this.caption); // Paper
}
/**
* Sets the caption on this cursor.
*
* @param caption new caption
+ * @deprecated in favour of {@link #caption(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
public void setCaption(@Nullable String caption) {
- this.caption = caption;
+ this.caption = caption == null ? null : net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(caption); // Paper
}
/**
diff --git a/src/main/java/org/bukkit/map/MapCursorCollection.java b/src/main/java/org/bukkit/map/MapCursorCollection.java
index 4dba721aefe4fc6699b3b4bfa7ecb0b19c2a2a1a..6bc28d000f538ecbf249467ff3e87e3f4fea963e 100644
--- a/src/main/java/org/bukkit/map/MapCursorCollection.java
+++ b/src/main/java/org/bukkit/map/MapCursorCollection.java
@@ -117,4 +117,22 @@ public final class MapCursorCollection {
public MapCursor addCursor(int x, int y, byte direction, byte type, boolean visible, @Nullable String caption) {
return addCursor(new MapCursor((byte) x, (byte) y, direction, type, visible, caption));
}
+ // Paper start
+ /**
+ * Add a cursor to the collection.
+ *
+ * @param x The x coordinate, from -128 to 127.
+ * @param y The y coordinate, from -128 to 127.
+ * @param direction The facing of the cursor, from 0 to 15.
+ * @param type The type (color/style) of the map cursor.
+ * @param visible Whether the cursor is visible.
+ * @param caption banner caption
+ * @return The newly added MapCursor.
+ * @deprecated Magic value
+ */
+ @Deprecated
+ public @NotNull MapCursor addCursor(int x, int y, byte direction, byte type, boolean visible, net.kyori.adventure.text.@Nullable 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 228421154913116069c20323afb519bdde2134df..26791db3c267670d5782f1d2b67ff7d5b55b9dac 100644
--- a/src/main/java/org/bukkit/permissions/Permissible.java
+++ b/src/main/java/org/bukkit/permissions/Permissible.java
@@ -126,4 +126,34 @@ public interface Permissible extends ServerOperator {
*/
@NotNull
public Set<PermissionAttachmentInfo> 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/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java
index 03ca87a1cbace2459174bb7bb8847bda766e80c5..b37938745f916b5f0111b07b1a1c97527f026e9d 100644
--- a/src/main/java/org/bukkit/plugin/Plugin.java
+++ b/src/main/java/org/bukkit/plugin/Plugin.java
@@ -179,6 +179,13 @@ public interface Plugin extends TabExecutor {
@NotNull
public Logger getLogger();
+ // Paper start - Adventure component logger
+ @NotNull
+ default net.kyori.adventure.text.logger.slf4j.ComponentLogger getComponentLogger() {
+ return net.kyori.adventure.text.logger.slf4j.ComponentLogger.logger(getLogger().getName());
+ }
+ // Paper end
+
/**
* Returns the name of the plugin.
* <p>
diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java
index 78fd35e6115072c6bc2ff5a899ffc2edb8f45801..22b1dc5fd4d453161a5ee520072f8e8f955b3a80 100644
--- a/src/main/java/org/bukkit/scoreboard/Objective.java
+++ b/src/main/java/org/bukkit/scoreboard/Objective.java
@@ -20,13 +20,35 @@ public interface Objective {
@NotNull
String getName();
+ // Paper start - Adventure
+ /**
+ * Gets the display name for this objective
+ *
+ * @return this objective's display name
+ * @throws IllegalStateException if this objective has been unregistered
+ */
+ net.kyori.adventure.text.@NotNull Component displayName();
+ /**
+ * Sets the name displayed to players for this objective.
+ *
+ * @param displayName Display name to set
+ * @throws IllegalStateException if this objective has been unregistered
+ * @throws IllegalArgumentException if displayName is null
+ * @throws IllegalArgumentException if displayName is longer than 128
+ * characters.
+ */
+ void displayName(net.kyori.adventure.text.@Nullable Component displayName);
+ // Paper end - Adventure
+
/**
* Gets the name displayed to players for this objective
*
* @return this objective's display name
* @throws IllegalStateException if this objective has been unregistered
+ * @deprecated in favour of {@link #displayName()}
*/
@NotNull
+ @Deprecated // Paper
String getDisplayName();
/**
@@ -34,7 +56,9 @@ public interface Objective {
*
* @param displayName Display name to set
* @throws IllegalStateException if this objective has been unregistered
+ * @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setDisplayName(@NotNull String displayName);
/**
diff --git a/src/main/java/org/bukkit/scoreboard/Scoreboard.java b/src/main/java/org/bukkit/scoreboard/Scoreboard.java
index 083bb2c92a2c557e10b705b773ced97401586c3c..d5723e977d9a25701a4f387f1b26d2414e0fffb8 100644
--- a/src/main/java/org/bukkit/scoreboard/Scoreboard.java
+++ b/src/main/java/org/bukkit/scoreboard/Scoreboard.java
@@ -26,6 +26,71 @@ public interface Scoreboard {
@NotNull
Objective registerNewObjective(@NotNull String name, @NotNull String criteria);
+ // Paper start - Adventure
+ /**
+ * Registers an Objective on this Scoreboard
+ *
+ * @param name Name of the Objective
+ * @param criteria Criteria for the Objective
+ * @param displayName display name for the Objective.
+ * @return The registered Objective
+ * @throws IllegalArgumentException if name is longer than 32767
+ * characters.
+ * @throws IllegalArgumentException if an objective by that name already
+ * exists
+ * @deprecated use {@link #registerNewObjective(String, Criteria, net.kyori.adventure.text.Component)}
+ */
+ @NotNull
+ @Deprecated
+ Objective registerNewObjective(@NotNull String name, @NotNull String criteria, net.kyori.adventure.text.@Nullable Component displayName);
+ /**
+ * Registers an Objective on this Scoreboard
+ *
+ * @param name Name of the Objective
+ * @param criteria Criteria for the Objective
+ * @param displayName Name displayed to players for the Objective.
+ * @param renderType Manner of rendering the Objective
+ * @return The registered Objective
+ * @throws IllegalArgumentException if name is longer than 32767
+ * characters.
+ * @throws IllegalArgumentException if an objective by that name already
+ * exists
+ * @deprecated use {@link #registerNewObjective(String, Criteria, net.kyori.adventure.text.Component, RenderType)}
+ */
+ @NotNull
+ @Deprecated
+ Objective registerNewObjective(@NotNull String name, @NotNull String criteria, net.kyori.adventure.text.@Nullable Component displayName, @NotNull RenderType renderType) throws IllegalArgumentException;
+ /**
+ * Registers an Objective on this Scoreboard
+ *
+ * @param name Name of the Objective
+ * @param criteria Criteria for the Objective
+ * @param displayName Name displayed to players for the Objective.
+ * @return The registered Objective
+ * @throws IllegalArgumentException if name is longer than 32767
+ * characters.
+ * @throws IllegalArgumentException if an objective by that name already
+ * exists
+ */
+ @NotNull
+ Objective registerNewObjective(@NotNull String name, @NotNull Criteria criteria, net.kyori.adventure.text.@Nullable Component displayName) throws IllegalArgumentException;
+ /**
+ * Registers an Objective on this Scoreboard
+ *
+ * @param name Name of the Objective
+ * @param criteria Criteria for the Objective
+ * @param displayName Name displayed to players for the Objective.
+ * @param renderType Manner of rendering the Objective
+ * @return The registered Objective
+ * @throws IllegalArgumentException if name is longer than 32767
+ * characters.
+ * @throws IllegalArgumentException if an objective by that name already
+ * exists
+ */
+ @NotNull
+ Objective registerNewObjective(@NotNull String name, @NotNull Criteria criteria, net.kyori.adventure.text.@Nullable Component displayName, @NotNull RenderType renderType) throws IllegalArgumentException;
+ // Paper end - Adventure
+
/**
* Registers an Objective on this Scoreboard
*
@@ -37,9 +102,10 @@ public interface Scoreboard {
* characters.
* @throws IllegalArgumentException if an objective by that name already
* exists
- * @deprecated use {@link #registerNewObjective(String, Criteria, String)}
+ * @deprecated use {@link #registerNewObjective(String, Criteria, net.kyori.adventure.text.Component)}
*/
@NotNull
+ @Deprecated // Paper
Objective registerNewObjective(@NotNull String name, @NotNull String criteria, @NotNull String displayName);
/**
@@ -54,9 +120,10 @@ public interface Scoreboard {
* characters.
* @throws IllegalArgumentException if an objective by that name already
* exists
- * @deprecated use {@link #registerNewObjective(String, Criteria, String, RenderType)}
+ * @deprecated use {@link #registerNewObjective(String, Criteria, net.kyori.adventure.text.Component, RenderType)}
*/
@NotNull
+ @Deprecated // Paper
Objective registerNewObjective(@NotNull String name, @NotNull String criteria, @NotNull String displayName, @NotNull RenderType renderType);
/**
@@ -70,8 +137,10 @@ public interface Scoreboard {
* characters.
* @throws IllegalArgumentException if an objective by that name already
* exists
+ * @deprecated in favour of {@link #registerNewObjective(String, Criteria, net.kyori.adventure.text.Component)}
*/
@NotNull
+ @Deprecated // Paper
Objective registerNewObjective(@NotNull String name, @NotNull Criteria criteria, @NotNull String displayName);
/**
@@ -86,8 +155,10 @@ public interface Scoreboard {
* characters.
* @throws IllegalArgumentException if an objective by that name already
* exists
+ * @deprecated in favour of {@link #registerNewObjective(String, Criteria, net.kyori.adventure.text.Component, RenderType)}
*/
@NotNull
+ @Deprecated // Paper
Objective registerNewObjective(@NotNull String name, @NotNull Criteria criteria, @NotNull String displayName, @NotNull RenderType renderType);
/**
diff --git a/src/main/java/org/bukkit/scoreboard/Team.java b/src/main/java/org/bukkit/scoreboard/Team.java
index 7b9a7890b25ca4bd95ab81f3181288bf79ed649c..52e8be769d2e9b69e9833bc9a7fe39afd10c5095 100644
--- a/src/main/java/org/bukkit/scoreboard/Team.java
+++ b/src/main/java/org/bukkit/scoreboard/Team.java
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable;
* properties. This team is only relevant to the display of the associated
* {@link #getScoreboard() scoreboard}.
*/
-public interface Team {
+public interface Team extends net.kyori.adventure.audience.ForwardingAudience { // Paper - Make Team extend ForwardingAudience
/**
* Gets the name of this Team
@@ -23,13 +23,96 @@ public interface Team {
@NotNull
String getName();
+ // Paper start - Adventure
+ /**
+ * Gets the display name for this team
+ *
+ * @return Team display name
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ net.kyori.adventure.text.@NotNull Component displayName();
+
+ /**
+ * Sets the name displayed to entries for this team
+ *
+ * @param displayName New display name
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ void displayName(net.kyori.adventure.text.@Nullable Component displayName);
+
+ /**
+ * Gets the prefix prepended to the display of entries on this team.
+ *
+ * @return Team prefix
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ net.kyori.adventure.text.@NotNull Component prefix();
+
+ /**
+ * Sets the prefix prepended to the display of entries on this team.
+ *
+ * @param prefix New prefix
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ void prefix(net.kyori.adventure.text.@Nullable Component prefix);
+
+ /**
+ * Gets the suffix appended to the display of entries on this team.
+ *
+ * @return the team's current suffix
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ net.kyori.adventure.text.@NotNull Component suffix();
+
+ /**
+ * Sets the suffix appended to the display of entries on this team.
+ *
+ * @param suffix the new suffix for this team.
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ void suffix(net.kyori.adventure.text.@Nullable Component suffix);
+
+ /**
+ * Checks if the team has a color specified
+ *
+ * @return true if it has a <b>color</b>
+ * @throws IllegalStateException if this team has been unregistered
+ */
+ boolean hasColor();
+
+ /**
+ * Gets the color of the team.
+ * <br>
+ * This only sets the team outline, other occurrences of colors such as in
+ * names are handled by prefixes / suffixes.
+ *
+ * @return team color
+ * @throws IllegalStateException if this team has been unregistered
+ * @throws IllegalStateException if the team doesn't have a color
+ * @see #hasColor()
+ */
+ net.kyori.adventure.text.format.@NotNull TextColor color();
+
+ /**
+ * Sets the color of the team.
+ * <br>
+ * This only sets the team outline, other occurrences of colors such as in
+ * names are handled by prefixes / suffixes.
+ *
+ * @param color new color, null for no color
+ */
+ void color(net.kyori.adventure.text.format.@Nullable NamedTextColor color);
+ // Paper end - Adventure
+
/**
* Gets the name displayed to entries for this team
*
* @return Team display name
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #displayName()}
*/
@NotNull
+ @Deprecated // Paper
String getDisplayName();
/**
@@ -37,7 +120,9 @@ public interface Team {
*
* @param displayName New display name
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #displayName(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setDisplayName(@NotNull String displayName);
/**
@@ -45,8 +130,10 @@ public interface Team {
*
* @return Team prefix
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #prefix()}
*/
@NotNull
+ @Deprecated // Paper
String getPrefix();
/**
@@ -54,7 +141,9 @@ public interface Team {
*
* @param prefix New prefix
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #prefix(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setPrefix(@NotNull String prefix);
/**
@@ -62,8 +151,10 @@ public interface Team {
*
* @return the team's current suffix
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #suffix()}
*/
@NotNull
+ @Deprecated // Paper
String getSuffix();
/**
@@ -71,7 +162,9 @@ public interface Team {
*
* @param suffix the new suffix for this team.
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #suffix(net.kyori.adventure.text.Component)}
*/
+ @Deprecated // Paper
void setSuffix(@NotNull String suffix);
/**
@@ -82,8 +175,10 @@ public interface Team {
*
* @return team color, defaults to {@link ChatColor#RESET}
* @throws IllegalStateException if this team has been unregistered
+ * @deprecated in favour of {@link #color()}
*/
@NotNull
+ @Deprecated // Paper
ChatColor getColor();
/**
@@ -94,7 +189,9 @@ public interface Team {
*
* @param color new color, must be non-null. Use {@link ChatColor#RESET} for
* no color
+ * @deprecated in favour of {@link #color(net.kyori.adventure.text.format.NamedTextColor)}
*/
+ @Deprecated // Paper
void setColor(@NotNull ChatColor color);
/**
diff --git a/src/test/java/io/papermc/paper/adventure/KeyTest.java b/src/test/java/io/papermc/paper/adventure/KeyTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ede17d60358e0e3a04f3166ea9657e5239e0d8f
--- /dev/null
+++ b/src/test/java/io/papermc/paper/adventure/KeyTest.java
@@ -0,0 +1,31 @@
+package io.papermc.paper.adventure;
+
+import java.util.HashSet;
+import java.util.Set;
+import net.kyori.adventure.key.Key;
+import org.bukkit.NamespacedKey;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class KeyTest {
+
+ @Test
+ public void equalsTest() {
+ Key key = new NamespacedKey("test", "key");
+ Key key1 = Key.key("test", "key");
+ assertEquals(key, key1);
+ assertEquals(key1, key);
+ }
+
+ @Test
+ public void setTest() {
+ Key key = new NamespacedKey("test", "key");
+ Key key1 = Key.key("test", "key");
+ Set<Key> set = new HashSet<>(Set.of(key));
+ Set<Key> set1 = new HashSet<>(Set.of(key1));
+ assertTrue(set.contains(key1));
+ assertTrue(set1.contains(key));
+ }
+}