mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-31 21:48:08 +01:00
Initial adventure implementation
- deprecate old text classes - make CommandSender and Audience - implement in ConsoleSender - partially implement in Player
This commit is contained in:
parent
7c63099963
commit
4f0944ba9f
@ -182,6 +182,13 @@ dependencies {
|
||||
|
||||
|
||||
generatorsImplementation("com.squareup:javapoet:1.13.0")
|
||||
|
||||
// Adventure, for text messages
|
||||
api platform("net.kyori:adventure-bom:4.5.1")
|
||||
api "net.kyori:adventure-api"
|
||||
implementation "net.kyori:adventure-text-serializer-gson"
|
||||
implementation "net.kyori:adventure-text-serializer-plain"
|
||||
implementation "net.kyori:adventure-text-serializer-legacy"
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
@ -5,6 +5,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Represents a click event for a specific portion of the message.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ChatClickEvent {
|
||||
|
||||
private final String action;
|
||||
|
@ -18,6 +18,7 @@ import java.util.Map;
|
||||
* <p>
|
||||
* Immutable class.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class ChatColor {
|
||||
|
||||
// Special
|
||||
|
@ -10,6 +10,7 @@ import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
/**
|
||||
* Represents a hover event for a specific portion of the message.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ChatHoverEvent {
|
||||
|
||||
private final String action;
|
||||
|
@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Class used to convert JSON string to proper chat message representation.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class ChatParser {
|
||||
|
||||
public static final char COLOR_CHAR = (char) 0xA7; // Represent the character '§'
|
||||
|
@ -17,6 +17,7 @@ import java.util.regex.Pattern;
|
||||
* To create one, you simply call one of the static methods like {@link #of(ChatColor, String)},
|
||||
* you can then continue to append text with {@link #append(ChatColor, String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class ColoredText extends JsonMessage {
|
||||
|
||||
private static final char SEPARATOR_START = '{';
|
||||
|
@ -3,6 +3,8 @@ package net.minestom.server.chat;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
@ -14,6 +16,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @see <a href="https://wiki.vg/Chat">Chat Format</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class JsonMessage {
|
||||
|
||||
// true if the compiled string is up-to-date, false otherwise
|
||||
@ -49,6 +52,14 @@ public abstract class JsonMessage {
|
||||
return getTextMessage(getJsonObject()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this JSON message as an Adventure Component.
|
||||
* @return the component
|
||||
*/
|
||||
public Component asComponent() {
|
||||
return GsonComponentSerializer.gson().deserialize(this.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Json representation.
|
||||
* <p>
|
||||
@ -102,6 +113,7 @@ public abstract class JsonMessage {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static class RawJsonMessage extends JsonMessage {
|
||||
|
||||
private final JsonObject jsonObject;
|
||||
|
@ -19,6 +19,7 @@ import java.util.List;
|
||||
* events can be assigned with {@link #setClickEvent(ChatClickEvent)} and {@link #setHoverEvent(ChatHoverEvent)}
|
||||
* and new text element can also be appended {@link #append(ColoredText)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class RichMessage extends JsonMessage {
|
||||
|
||||
private final List<RichComponent> components = new ArrayList<>();
|
||||
|
@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a translatable component which can be used in {@link ColoredText}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TranslatableText {
|
||||
|
||||
private final String code;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.minestom.server.command;
|
||||
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.permission.PermissionHandler;
|
||||
@ -10,20 +12,26 @@ import org.jetbrains.annotations.NotNull;
|
||||
* <p>
|
||||
* Main implementations are {@link Player} and {@link ConsoleSender}.
|
||||
*/
|
||||
public interface CommandSender extends PermissionHandler {
|
||||
public interface CommandSender extends PermissionHandler, Audience {
|
||||
|
||||
/**
|
||||
* Sends a raw string message.
|
||||
*
|
||||
* @param message the message to send
|
||||
*
|
||||
* @deprecated Use {@link #sendMessage(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
void sendMessage(@NotNull String message);
|
||||
|
||||
/**
|
||||
* Sends multiple raw string messages.
|
||||
*
|
||||
* @param messages the messages to send
|
||||
*
|
||||
* @deprecated Use {@link #sendMessage(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
default void sendMessage(@NotNull String[] messages) {
|
||||
for (String message : messages) {
|
||||
sendMessage(message);
|
||||
@ -35,13 +43,12 @@ public interface CommandSender extends PermissionHandler {
|
||||
* If this is not a {@link Player}, only the content of the message will be sent as a string.
|
||||
*
|
||||
* @param text The {@link JsonMessage} to send.
|
||||
*
|
||||
* @deprecated Use {@link #sendMessage(Component)}
|
||||
* */
|
||||
@Deprecated
|
||||
default void sendMessage(@NotNull JsonMessage text) {
|
||||
if (this instanceof Player) {
|
||||
this.sendMessage(text);
|
||||
} else {
|
||||
sendMessage(text.getRawMessage());
|
||||
}
|
||||
this.sendMessage(text.asComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,11 @@
|
||||
package net.minestom.server.command;
|
||||
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
||||
import net.minestom.server.permission.Permission;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -17,6 +22,11 @@ public class ConsoleSender implements CommandSender {
|
||||
|
||||
private final Set<Permission> permissions = new CopyOnWriteArraySet<>();
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NonNull Identity source, @NonNull Component message, @NonNull MessageType type) {
|
||||
LOGGER.info(PlainComponentSerializer.plain().serialize(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NotNull String message) {
|
||||
LOGGER.info(message);
|
||||
|
@ -1,6 +1,14 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import com.google.common.collect.Queues;
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.inventory.Book;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.advancements.AdvancementTab;
|
||||
import net.minestom.server.attribute.Attribute;
|
||||
@ -59,6 +67,7 @@ import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -766,6 +775,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param message the message to send,
|
||||
* you can use {@link ColoredText} and/or {@link RichMessage} to create it easily
|
||||
*/
|
||||
@Override
|
||||
public void sendMessage(@NotNull JsonMessage message) {
|
||||
sendJsonMessage(message.toString());
|
||||
}
|
||||
@ -775,7 +785,10 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
*
|
||||
* @param text the text with the legacy color formatting
|
||||
* @param colorChar the color character
|
||||
*
|
||||
* @deprecated Use {@link #sendMessage(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendLegacyMessage(@NotNull String text, char colorChar) {
|
||||
ColoredText coloredText = ColoredText.ofLegacy(text, colorChar);
|
||||
sendJsonMessage(coloredText.toString());
|
||||
@ -785,15 +798,26 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* Sends a legacy message with the default color char {@link ChatParser#COLOR_CHAR}.
|
||||
*
|
||||
* @param text the text with the legacy color formatting
|
||||
*
|
||||
* @deprecated Use {@link #sendMessage(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendLegacyMessage(@NotNull String text) {
|
||||
ColoredText coloredText = ColoredText.ofLegacy(text, ChatParser.COLOR_CHAR);
|
||||
sendJsonMessage(coloredText.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #sendMessage(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendJsonMessage(@NotNull String json) {
|
||||
ChatMessagePacket chatMessagePacket =
|
||||
new ChatMessagePacket(json, ChatMessagePacket.Position.CHAT);
|
||||
this.sendMessage(json);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NonNull Identity source, @NonNull Component message, @NonNull MessageType type) {
|
||||
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(GsonComponentSerializer.gson().serialize(message), type, source.uuid());
|
||||
playerConnection.sendPacket(chatMessagePacket);
|
||||
}
|
||||
|
||||
@ -926,13 +950,21 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
*
|
||||
* @param header the header text, null to set empty
|
||||
* @param footer the footer text, null to set empty
|
||||
*
|
||||
* @deprecated Use {@link #sendPlayerListHeaderAndFooter(Component, Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendHeaderFooter(@Nullable JsonMessage header, @Nullable JsonMessage footer) {
|
||||
PlayerListHeaderAndFooterPacket playerListHeaderAndFooterPacket = new PlayerListHeaderAndFooterPacket();
|
||||
playerListHeaderAndFooterPacket.header = header;
|
||||
playerListHeaderAndFooterPacket.footer = footer;
|
||||
this.sendPlayerListHeaderAndFooter(header == null ? Component.empty() : header.asComponent(),
|
||||
footer == null ? Component.empty() : footer.asComponent());
|
||||
}
|
||||
|
||||
playerConnection.sendPacket(playerListHeaderAndFooterPacket);
|
||||
@Override
|
||||
public void sendPlayerListHeaderAndFooter(@NonNull Component header, @NonNull Component footer) {
|
||||
playerConnection.sendPacket(new PlayerListHeaderAndFooterPacket(
|
||||
GsonComponentSerializer.gson().serialize(header),
|
||||
GsonComponentSerializer.gson().serialize(footer)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -941,25 +973,12 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param text the text of the title
|
||||
* @param action the action of the title (where to show it)
|
||||
* @see #sendTitleTime(int, int, int) to specify the display time
|
||||
*
|
||||
* @deprecated Use {@link #showTitle(Title)} and {@link #sendActionBar(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
private void sendTitle(@NotNull JsonMessage text, @NotNull TitlePacket.Action action) {
|
||||
TitlePacket titlePacket = new TitlePacket();
|
||||
titlePacket.action = action;
|
||||
|
||||
switch (action) {
|
||||
case SET_TITLE:
|
||||
titlePacket.titleText = text;
|
||||
break;
|
||||
case SET_SUBTITLE:
|
||||
titlePacket.subtitleText = text;
|
||||
break;
|
||||
case SET_ACTION_BAR:
|
||||
titlePacket.actionBarText = text;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Invalid TitlePacket.Action type!");
|
||||
}
|
||||
|
||||
TitlePacket titlePacket = new TitlePacket(action, text.toString());
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
@ -969,10 +988,12 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param title the title message
|
||||
* @param subtitle the subtitle message
|
||||
* @see #sendTitleTime(int, int, int) to specify the display time
|
||||
*
|
||||
* @deprecated Use {@link #showTitle(Title)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendTitleSubtitleMessage(@NotNull JsonMessage title, @NotNull JsonMessage subtitle) {
|
||||
sendTitle(title, TitlePacket.Action.SET_TITLE);
|
||||
sendTitle(subtitle, TitlePacket.Action.SET_SUBTITLE);
|
||||
this.showTitle(Title.title(title.asComponent(), subtitle.asComponent()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -980,9 +1001,12 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
*
|
||||
* @param title the title message
|
||||
* @see #sendTitleTime(int, int, int) to specify the display time
|
||||
*
|
||||
* @deprecated Use {@link #showTitle(Title)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendTitleMessage(@NotNull JsonMessage title) {
|
||||
sendTitle(title, TitlePacket.Action.SET_TITLE);
|
||||
this.showTitle(Title.title(title.asComponent(), Component.empty()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -990,9 +1014,12 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
*
|
||||
* @param subtitle the subtitle message
|
||||
* @see #sendTitleTime(int, int, int) to specify the display time
|
||||
*
|
||||
* @deprecated Use {@link #showTitle(Title)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendSubtitleMessage(@NotNull JsonMessage subtitle) {
|
||||
sendTitle(subtitle, TitlePacket.Action.SET_SUBTITLE);
|
||||
this.showTitle(Title.title(Component.empty(), subtitle.asComponent()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1000,9 +1027,25 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
*
|
||||
* @param actionBar the action bar message
|
||||
* @see #sendTitleTime(int, int, int) to specify the display time
|
||||
*
|
||||
* @deprecated Use {@link #sendActionBar(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendActionBarMessage(@NotNull JsonMessage actionBar) {
|
||||
sendTitle(actionBar, TitlePacket.Action.SET_ACTION_BAR);
|
||||
this.sendActionBar(actionBar.asComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showTitle(@NonNull Title title) {
|
||||
for (TitlePacket titlePacket : TitlePacket.of(title)) {
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendActionBar(@NonNull Component message) {
|
||||
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, GsonComponentSerializer.gson().serialize(message));
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1011,31 +1054,40 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param fadeIn ticks to spend fading in
|
||||
* @param stay ticks to keep the title displayed
|
||||
* @param fadeOut ticks to spend out, not when to start fading out
|
||||
*
|
||||
* @deprecated Use {@link #showTitle(Title)}. Note that this will overwrite the
|
||||
* existing title. This is expected behavior and will be the case in 1.17.
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendTitleTime(int fadeIn, int stay, int fadeOut) {
|
||||
TitlePacket titlePacket = new TitlePacket();
|
||||
titlePacket.action = TitlePacket.Action.SET_TIMES_AND_DISPLAY;
|
||||
titlePacket.fadeIn = fadeIn;
|
||||
titlePacket.stay = stay;
|
||||
titlePacket.fadeOut = fadeOut;
|
||||
TitlePacket titlePacket = new TitlePacket(fadeIn, stay, fadeOut);
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the previous title.
|
||||
* @deprecated Use {@link #clearTitle()}. Note this title cannot be shown again. This
|
||||
* is expected behavior and will be the case in 1.17.
|
||||
*/
|
||||
@Deprecated
|
||||
public void hideTitle() {
|
||||
TitlePacket titlePacket = new TitlePacket();
|
||||
titlePacket.action = TitlePacket.Action.HIDE;
|
||||
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.HIDE);
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the previous title.
|
||||
* @deprecated Use {@link #clearTitle()}. Note this title cannot be shown again. This
|
||||
* is expected behavior and will be the case in 1.17.
|
||||
*/
|
||||
public void resetTitle() {
|
||||
TitlePacket titlePacket = new TitlePacket();
|
||||
titlePacket.action = TitlePacket.Action.RESET;
|
||||
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.RESET);
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTitle() {
|
||||
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.RESET);
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
@ -1043,7 +1095,10 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* Opens a book ui for the player with the given book metadata.
|
||||
*
|
||||
* @param bookMeta The metadata of the book to open
|
||||
*
|
||||
* @deprecated Use {@link #openBook(Book)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void openBook(@NotNull WrittenBookMeta bookMeta) {
|
||||
// Set book in offhand
|
||||
final ItemStack writtenBook = new ItemStack(Material.WRITTEN_BOOK, (byte) 1);
|
||||
@ -1063,6 +1118,11 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
this.inventory.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openBook(@NonNull Book book) {
|
||||
// TODO write the book
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isImmune(@NotNull DamageType type) {
|
||||
if (!getGameMode().canTakeDamage()) {
|
||||
@ -1730,16 +1790,40 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* Kicks the player with a reason.
|
||||
*
|
||||
* @param text the kick reason
|
||||
*
|
||||
* @deprecated Use {@link #kick(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void kick(@NotNull JsonMessage text) {
|
||||
this.kick(text.asComponent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the player with a reason.
|
||||
*
|
||||
* @param message the kick reason
|
||||
*
|
||||
* @deprecated Use {@link #kick(Component)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void kick(@NotNull String message) {
|
||||
this.kick(Component.text(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the player with a reason.
|
||||
*
|
||||
* @param component the reason
|
||||
*/
|
||||
public void kick(@NotNull Component component) {
|
||||
final ConnectionState connectionState = playerConnection.getConnectionState();
|
||||
|
||||
// Packet type depends on the current player connection state
|
||||
final ServerPacket disconnectPacket;
|
||||
if (connectionState == ConnectionState.LOGIN) {
|
||||
disconnectPacket = new LoginDisconnectPacket(text);
|
||||
disconnectPacket = new LoginDisconnectPacket(GsonComponentSerializer.gson().serialize(component));
|
||||
} else {
|
||||
disconnectPacket = new DisconnectPacket(text);
|
||||
disconnectPacket = new DisconnectPacket(GsonComponentSerializer.gson().serialize(component));
|
||||
}
|
||||
|
||||
if (playerConnection instanceof NettyPlayerConnection) {
|
||||
@ -1751,15 +1835,6 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the player with a reason.
|
||||
*
|
||||
* @param message the kick reason
|
||||
*/
|
||||
public void kick(@NotNull String message) {
|
||||
kick(ColoredText.of(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the current held slot for the player.
|
||||
*
|
||||
|
@ -1,32 +1,68 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents an outgoing chat message packet. Do not use this to send messages above the
|
||||
* hotbar (the game info position) as it is preferred to use
|
||||
* {@link TitlePacket} due to <a href="https://bugs.mojang.com/browse/MC-119145">MC-119145</a>.
|
||||
*/
|
||||
public class ChatMessagePacket implements ServerPacket {
|
||||
private static final UUID NULL_UUID = new UUID(0, 0);
|
||||
|
||||
public String jsonMessage;
|
||||
public Position position;
|
||||
public MessageType messageType;
|
||||
public UUID uuid;
|
||||
|
||||
@Deprecated
|
||||
public ChatMessagePacket(String jsonMessage, Position position, UUID uuid) {
|
||||
this.jsonMessage = jsonMessage;
|
||||
this.position = position;
|
||||
this.uuid = uuid;
|
||||
this(jsonMessage, position.asMessageType(), uuid);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ChatMessagePacket(String jsonMessage, Position position) {
|
||||
this(jsonMessage, position, new UUID(0, 0));
|
||||
this(jsonMessage, position, NULL_UUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new chat message packet with a zeroed UUID. To send formatted
|
||||
* messages please use the respective {@link Audience#sendMessage(Component)}
|
||||
* functions.
|
||||
*
|
||||
* @param jsonMessage the raw message payload
|
||||
* @param messageType the message type
|
||||
*/
|
||||
public ChatMessagePacket(String jsonMessage, MessageType messageType) {
|
||||
this(jsonMessage, messageType, NULL_UUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new chat message packet. To send formatted messages please use the
|
||||
* respective {@link Audience#sendMessage(Component)} functions.
|
||||
*
|
||||
* @param jsonMessage the raw message payload
|
||||
* @param messageType the message type
|
||||
* @param uuid the sender of the chat message
|
||||
*/
|
||||
public ChatMessagePacket(String jsonMessage, MessageType messageType, UUID uuid) {
|
||||
this.jsonMessage = jsonMessage;
|
||||
this.messageType = messageType;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeSizedString(jsonMessage);
|
||||
writer.writeByte((byte) position.ordinal());
|
||||
writer.writeByte((byte) (messageType == null ? 3 : messageType.ordinal()));
|
||||
writer.writeUuid(uuid);
|
||||
}
|
||||
|
||||
@ -35,9 +71,29 @@ public class ChatMessagePacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.CHAT_MESSAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link MessageType}
|
||||
*/
|
||||
@Deprecated
|
||||
public enum Position {
|
||||
CHAT,
|
||||
SYSTEM_MESSAGE,
|
||||
GAME_INFO
|
||||
CHAT(MessageType.CHAT),
|
||||
SYSTEM_MESSAGE(MessageType.SYSTEM),
|
||||
GAME_INFO(null);
|
||||
|
||||
private final MessageType messageType;
|
||||
|
||||
Position(MessageType messageType) {
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this position as an Adventure message type. Note this will return
|
||||
* {@code null} for {@link #GAME_INFO} as it is preferred to use
|
||||
* {@link TitlePacket} due to <a href="https://bugs.mojang.com/browse/MC-119145">MC-119145</a>.
|
||||
* @return the message type
|
||||
*/
|
||||
public @Nullable MessageType asMessageType() {
|
||||
return this.messageType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
@ -7,16 +8,27 @@ import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DisconnectPacket implements ServerPacket {
|
||||
private String payload;
|
||||
|
||||
public JsonMessage message; // Only text
|
||||
/**
|
||||
* Creates a new disconnect packet with a given string.
|
||||
* @param payload the message
|
||||
*/
|
||||
public DisconnectPacket(@NotNull String payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #DisconnectPacket(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public DisconnectPacket(@NotNull JsonMessage message){
|
||||
this.message = message;
|
||||
this(message.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeSizedString(message.toString());
|
||||
writer.writeSizedString(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,31 +1,26 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlayerListHeaderAndFooterPacket implements ServerPacket {
|
||||
public String header;
|
||||
public String footer;
|
||||
|
||||
private static final String EMPTY_COMPONENT = "{\"translate\":\"\"}";
|
||||
|
||||
public JsonMessage header; // Only text
|
||||
public JsonMessage footer; // Only text
|
||||
public PlayerListHeaderAndFooterPacket(@NotNull String header, @NotNull String footer) {
|
||||
Validate.notNull(header, "Header cannot be null.");
|
||||
Validate.notNull(footer, "Footer cannot be null.");
|
||||
this.header = header;
|
||||
this.footer = footer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
if (header == null) {
|
||||
writer.writeSizedString(EMPTY_COMPONENT);
|
||||
} else {
|
||||
writer.writeSizedString(header.toString());
|
||||
}
|
||||
|
||||
if (footer == null) {
|
||||
writer.writeSizedString(EMPTY_COMPONENT);
|
||||
} else {
|
||||
writer.writeSizedString(footer.toString());
|
||||
}
|
||||
writer.writeSizedString(header);
|
||||
writer.writeSizedString(footer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,24 +1,64 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.TickUtils;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static net.minestom.server.network.packet.server.play.TitlePacket.Action.*;
|
||||
|
||||
public class TitlePacket implements ServerPacket {
|
||||
|
||||
public Action action;
|
||||
private Action action;
|
||||
|
||||
public JsonMessage titleText; // Only text
|
||||
private String payload;
|
||||
|
||||
public JsonMessage subtitleText; // Only text
|
||||
private int fadeIn, stay, fadeOut;
|
||||
|
||||
public JsonMessage actionBarText; // Only text
|
||||
/**
|
||||
* Constructs a new title packet from an action that can take a string argument.
|
||||
* @param action the action
|
||||
* @param payload the payload
|
||||
* @throws IllegalArgumentException if the action is not {@link Action#SET_TITLE},
|
||||
* {@link Action#SET_SUBTITLE} or {@link Action#SET_ACTION_BAR}
|
||||
*/
|
||||
public TitlePacket(@NotNull Action action, @NotNull String payload) {
|
||||
Validate.isTrue(action == SET_TITLE || action == SET_SUBTITLE || action == SET_ACTION_BAR, "Invalid action type");
|
||||
this.action = action;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public int fadeIn;
|
||||
public int stay;
|
||||
public int fadeOut;
|
||||
/**
|
||||
* Constructs a new title packet from a clear or reset action.
|
||||
* @param action the action
|
||||
* @throws IllegalArgumentException if the action is not {@link Action#RESET},
|
||||
* or {@link Action#HIDE}
|
||||
*/
|
||||
public TitlePacket(@NotNull Action action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new title packet for {@link Action#SET_TIMES_AND_DISPLAY}.
|
||||
* @param fadeIn the fade in time
|
||||
* @param stay the stay time
|
||||
* @param fadeOut the fade out time
|
||||
*/
|
||||
public TitlePacket(int fadeIn, int stay, int fadeOut) {
|
||||
this.action = SET_TIMES_AND_DISPLAY;
|
||||
this.fadeIn = fadeIn;
|
||||
this.stay = stay;
|
||||
this.fadeOut = fadeOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
@ -26,13 +66,9 @@ public class TitlePacket implements ServerPacket {
|
||||
|
||||
switch (action) {
|
||||
case SET_TITLE:
|
||||
writer.writeSizedString(titleText.toString());
|
||||
break;
|
||||
case SET_SUBTITLE:
|
||||
writer.writeSizedString(subtitleText.toString());
|
||||
break;
|
||||
case SET_ACTION_BAR:
|
||||
writer.writeSizedString(actionBarText.toString());
|
||||
writer.writeSizedString(payload);
|
||||
break;
|
||||
case SET_TIMES_AND_DISPLAY:
|
||||
writer.writeInt(fadeIn);
|
||||
@ -59,4 +95,25 @@ public class TitlePacket implements ServerPacket {
|
||||
RESET
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a collection of title packets from an Adventure title.
|
||||
* @param title the title
|
||||
* @return the packets
|
||||
*/
|
||||
public static Collection<TitlePacket> of(Title title) {
|
||||
List<TitlePacket> packets = new ArrayList<>(4);
|
||||
|
||||
// base packets
|
||||
packets.add(new TitlePacket(SET_TITLE, GsonComponentSerializer.gson().serialize(title.title())));
|
||||
packets.add(new TitlePacket(SET_SUBTITLE, GsonComponentSerializer.gson().serialize(title.subtitle())));
|
||||
|
||||
// times packet
|
||||
Title.Times times = title.times();
|
||||
if (times != null) {
|
||||
packets.add(new TitlePacket(TickUtils.fromDuration(times.fadeIn()), TickUtils.fromDuration(times.stay()),
|
||||
TickUtils.fromDuration(times.fadeOut())));
|
||||
}
|
||||
|
||||
return packets;
|
||||
}
|
||||
}
|
||||
|
25
src/main/java/net/minestom/server/utils/TickUtils.java
Normal file
25
src/main/java/net/minestom/server/utils/TickUtils.java
Normal file
@ -0,0 +1,25 @@
|
||||
package net.minestom.server.utils;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* Tick related utilities.
|
||||
*/
|
||||
public class TickUtils {
|
||||
|
||||
/**
|
||||
* Creates a number of ticks from a given duration, based on {@link MinecraftServer#TICK_MS}.
|
||||
* @param duration the duration
|
||||
* @return the number of ticks
|
||||
* @throws IllegalArgumentException if duration is negative
|
||||
*/
|
||||
public static int fromDuration(@NotNull Duration duration) {
|
||||
Validate.isTrue(!duration.isNegative(), "Duration cannot be negative");
|
||||
|
||||
return (int) (duration.toMillis() / MinecraftServer.TICK_MS);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user