From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Techcable Date: Mon, 29 Feb 2016 20:02:40 -0600 Subject: [PATCH] Player Tab List and Title APIs Co-authored-by: Fruxz diff --git a/src/main/java/com/destroystokyo/paper/Title.java b/src/main/java/com/destroystokyo/paper/Title.java new file mode 100644 index 0000000000000000000000000000000000000000..5105dfcee646718cd8abc79d1d8062a580b4e923 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/Title.java @@ -0,0 +1,417 @@ +package com.destroystokyo.paper; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +/** + * Represents a title to may be sent to a {@link Player}. + * + *

A title can be sent without subtitle text.

+ */ +public final class Title { + + /** + * The default number of ticks for the title to fade in. + */ + public static final int DEFAULT_FADE_IN = 20; + /** + * The default number of ticks for the title to stay. + */ + public static final int DEFAULT_STAY = 200; + /** + * The default number of ticks for the title to fade out. + */ + public static final int DEFAULT_FADE_OUT = 20; + + private final BaseComponent[] title; + private final BaseComponent[] subtitle; + private final int fadeIn; + private final int stay; + private final int fadeOut; + + /** + * Create a title with the default time values and no subtitle. + * + *

Times use default values.

+ * + * @param title the main text of the title + * @throws NullPointerException if the title is null + */ + public Title(@NotNull BaseComponent title) { + this(title, null); + } + + /** + * Create a title with the default time values and no subtitle. + * + *

Times use default values.

+ * + * @param title the main text of the title + * @throws NullPointerException if the title is null + */ + public Title(@NotNull BaseComponent[] title) { + this(title, null); + } + + /** + * Create a title with the default time values and no subtitle. + * + *

Times use default values.

+ * + * @param title the main text of the title + * @throws NullPointerException if the title is null + */ + public Title(@NotNull String title) { + this(title, null); + } + + /** + * Create a title with the default time values. + * + *

Times use default values.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + */ + public Title(@NotNull BaseComponent title, @Nullable BaseComponent subtitle) { + this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT); + } + + /** + * Create a title with the default time values. + * + *

Times use default values.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + */ + public Title(@NotNull BaseComponent[] title, @Nullable BaseComponent[] subtitle) { + this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT); + } + + /** + * Create a title with the default time values. + * + *

Times use default values.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + */ + public Title(@NotNull String title, @Nullable String subtitle) { + this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT); + } + + /** + * Creates a new title. + * + * @param title the main text of the title + * @param subtitle the secondary text of the title + * @param fadeIn the number of ticks for the title to fade in + * @param stay the number of ticks for the title to stay on screen + * @param fadeOut the number of ticks for the title to fade out + * @throws IllegalArgumentException if any of the times are negative + */ + public Title(@NotNull BaseComponent title, @Nullable BaseComponent subtitle, int fadeIn, int stay, int fadeOut) { + this( + new BaseComponent[]{checkNotNull(title, "title")}, + subtitle == null ? null : new BaseComponent[]{subtitle}, + fadeIn, + stay, + fadeOut + ); + } + + /** + * Creates a new title. + * + * @param title the main text of the title + * @param subtitle the secondary text of the title + * @param fadeIn the number of ticks for the title to fade in + * @param stay the number of ticks for the title to stay on screen + * @param fadeOut the number of ticks for the title to fade out + * @throws IllegalArgumentException if any of the times are negative + */ + public Title(@Nullable BaseComponent[] title, @NotNull BaseComponent[] subtitle, int fadeIn, int stay, int fadeOut) { + checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn); + checkArgument(stay >= 0, "Negative stay: %s", stay); + checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut); + this.title = checkNotNull(title, "title"); + this.subtitle = subtitle; + this.fadeIn = fadeIn; + this.stay = stay; + this.fadeOut = fadeOut; + } + + /** + * Creates a new title. + * + *

It is recommended to the {@link BaseComponent} constrctors.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + * @param fadeIn the number of ticks for the title to fade in + * @param stay the number of ticks for the title to stay on screen + * @param fadeOut the number of ticks for the title to fade out + */ + public Title(@NotNull String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut) { + this( + TextComponent.fromLegacyText(checkNotNull(title, "title")), + subtitle == null ? null : TextComponent.fromLegacyText(subtitle), + fadeIn, + stay, + fadeOut + ); + } + + /** + * Gets the text of this title + * + * @return the text + */ + @NotNull + public BaseComponent[] getTitle() { + return this.title; + } + + /** + * Gets the text of this title's subtitle + * + * @return the text + */ + @Nullable + public BaseComponent[] getSubtitle() { + return this.subtitle; + } + + /** + * Gets the number of ticks to fade in. + * + *

The returned value is never negative.

+ * + * @return the number of ticks to fade in + */ + public int getFadeIn() { + return this.fadeIn; + } + + /** + * Gets the number of ticks to stay. + * + *

The returned value is never negative.

+ * + * @return the number of ticks to stay + */ + public int getStay() { + return this.stay; + } + + /** + * Gets the number of ticks to fade out. + * + *

The returned value is never negative.

+ * + * @return the number of ticks to fade out + */ + public int getFadeOut() { + return this.fadeOut; + } + + /** + * Sends the title directly to an player + * + * @param player the receiver of the title + */ + public void send(@NotNull Player player) { + player.sendTitle(this); + } + + /** + * Sends the title directly to the defined players + * + * @param players the receivers of the title + */ + public void send(@NotNull Collection players) { + for (Player player : players) { + player.sendTitle(this); + } + } + + /** + * Sends the title directly to the defined players + * + * @param players the receivers of the title + */ + public void send(@NotNull Player[] players) { + for (Player player : players) { + player.sendTitle(this); + } + } + + /** + * Sends the title directly to all online players + */ + public void broadcast() { + send(Bukkit.getOnlinePlayers()); + } + + @NotNull + public static Builder builder() { + return new Builder(); + } + + /** + * A builder for creating titles + */ + public static final class Builder { + + private BaseComponent[] title; + private BaseComponent[] subtitle; + private int fadeIn = DEFAULT_FADE_IN; + private int stay = DEFAULT_STAY; + private int fadeOut = DEFAULT_FADE_OUT; + + /** + * Sets the title to the given text. + * + * @param title the title text + * @return this builder instance + * @throws NullPointerException if the title is null + */ + @NotNull + public Builder title(@NotNull BaseComponent title) { + return this.title(new BaseComponent[]{checkNotNull(title, "title")}); + } + + /** + * Sets the title to the given text. + * + * @param title the title text + * @return this builder instance + * @throws NullPointerException if the title is null + */ + @NotNull + public Builder title(@NotNull BaseComponent[] title) { + this.title = checkNotNull(title, "title"); + return this; + } + + /** + * Sets the title to the given text. + * + *

It is recommended to the {@link BaseComponent} methods.

+ * + * @param title the title text + * @return this builder instance + * @throws NullPointerException if the title is null + */ + @NotNull + public Builder title(@NotNull String title) { + return this.title(TextComponent.fromLegacyText(checkNotNull(title, "title"))); + } + + /** + * Sets the subtitle to the given text. + * + * @param subtitle the title text + * @return this builder instance + */ + @NotNull + public Builder subtitle(@Nullable BaseComponent subtitle) { + return this.subtitle(subtitle == null ? null : new BaseComponent[]{subtitle}); + } + + /** + * Sets the subtitle to the given text. + * + * @param subtitle the title text + * @return this builder instance + */ + @NotNull + public Builder subtitle(@Nullable BaseComponent[] subtitle) { + this.subtitle = subtitle; + return this; + } + + /** + * Sets the subtitle to the given text. + * + *

It is recommended to the {@link BaseComponent} methods.

+ * + * @param subtitle the title text + * @return this builder instance + */ + @NotNull + public Builder subtitle(@Nullable String subtitle) { + return this.subtitle(subtitle == null ? null : TextComponent.fromLegacyText(subtitle)); + } + + /** + * Sets the number of ticks for the title to fade in + * + * @param fadeIn the number of ticks to fade in + * @return this builder instance + * @throws IllegalArgumentException if it is negative + */ + @NotNull + public Builder fadeIn(int fadeIn) { + checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn); + this.fadeIn = fadeIn; + return this; + } + + + /** + * Sets the number of ticks for the title to stay. + * + * @param stay the number of ticks to stay + * @return this builder instance + * @throws IllegalArgumentException if it is negative + */ + @NotNull + public Builder stay(int stay) { + checkArgument(stay >= 0, "Negative stay: %s", stay); + this.stay = stay; + return this; + } + + /** + * Sets the number of ticks for the title to fade out. + * + * @param fadeOut the number of ticks to fade out + * @return this builder instance + * @throws IllegalArgumentException if it is negative + */ + @NotNull + public Builder fadeOut(int fadeOut) { + checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut); + this.fadeOut = fadeOut; + return this; + } + + /** + * Create a title based on the values in the builder. + * + * @return a title from the values in this builder + * @throws IllegalStateException if title isn't specified + */ + @NotNull + public Title build() { + checkState(title != null, "Title not specified"); + return new Title(this.title, this.subtitle, this.fadeIn, this.stay, this.fadeOut); + } + } +} diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index 5553f465e45238b2f6c4041e2b5a58aea727543c..7889e98443d1192ae633ff64584f00255725c9bd 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -2,6 +2,7 @@ package org.bukkit.entity; import java.net.InetSocketAddress; import java.util.UUID; +import com.destroystokyo.paper.Title; // Paper import org.bukkit.DyeColor; import org.bukkit.Effect; import org.bukkit.GameMode; @@ -512,6 +513,116 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) { spigot().sendMessage(position, components); } + + /** + * Set the text displayed in the player list header and footer for this player + * + * @param header content for the top of the player list + * @param footer content for the bottom of the player list + */ + public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent[] header, @Nullable net.md_5.bungee.api.chat.BaseComponent[] footer); + + /** + * Set the text displayed in the player list header and footer for this player + * + * @param header content for the top of the player list + * @param footer content for the bottom of the player list + */ + public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent header, @Nullable net.md_5.bungee.api.chat.BaseComponent footer); + + /** + * Update the times for titles displayed to the player + * + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out + * @deprecated Use {@link #updateTitle(Title)} + */ + @Deprecated + public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks); + + /** + * Update the subtitle of titles displayed to the player + * + * @deprecated Use {@link #updateTitle(Title)} + */ + @Deprecated + public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent[] subtitle); + + /** + * Update the subtitle of titles displayed to the player + * + * @deprecated Use {@link #updateTitle(Title)} + */ + @Deprecated + public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent subtitle); + + /** + * Show the given title to the player, along with the last subtitle set, using the last set times + * + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title); + + /** + * Show the given title to the player, along with the last subtitle set, using the last set times + * + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title); + + /** + * Show the given title and subtitle to the player using the given times + * + * @param title big text + * @param subtitle little text under it + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title, @Nullable net.md_5.bungee.api.chat.BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); + + /** + * Show the given title and subtitle to the player using the given times + * + * @param title big text + * @param subtitle little text under it + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title, @Nullable net.md_5.bungee.api.chat.BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); + + /** + * Show the title to the player, overriding any previously displayed title. + * + *

This method overrides any previous title, use {@link #updateTitle(Title)} to change the existing one.

+ * + * @param title the title to send + * @throws NullPointerException if the title is null + */ + void sendTitle(@NotNull Title title); + + /** + * Show the title to the player, overriding any previously displayed title. + * + *

This method doesn't override previous titles, but changes their values.

+ * + * @param title the title to send + * @throws NullPointerException if title is null + */ + void updateTitle(@NotNull Title title); + + /** + * Hide any title that is currently visible to the player + */ + public void hideTitle(); // Paper end /**