begin bringing packets back to use components

This commit is contained in:
Kieran Wallbanks 2021-03-10 16:13:27 +00:00
parent 35e057a638
commit 327558c003
32 changed files with 399 additions and 325 deletions

View File

@ -1,7 +1,6 @@
package net.minestom.server.advancements;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.item.ItemStack;
@ -375,8 +374,8 @@ public class Advancement {
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
displayData.x = x;
displayData.y = y;
displayData.title = MinecraftServer.getSerializationManager().serialize(title);
displayData.description = MinecraftServer.getSerializationManager().serialize(description);
displayData.title = title;
displayData.description = description;
displayData.icon = icon;
displayData.frameType = frameType;
displayData.flags = getFlags();

View File

@ -1,6 +1,6 @@
package net.minestom.server.advancements.notifications;
import net.minestom.server.MinecraftServer;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.play.AdvancementsPacket;
import net.minestom.server.network.player.PlayerConnection;
@ -82,9 +82,9 @@ public class NotificationCenter {
// Setup display data for the advancement
AdvancementsPacket.DisplayData displayData = new AdvancementsPacket.DisplayData();
{
displayData.title = MinecraftServer.getSerializationManager().serialize(notification.getTitle());
displayData.title = notification.getTitle();
// Description is required, but never shown/seen so, small Easter egg.
displayData.description = "Articdive was here. #Minestom";
displayData.description = Component.text("Articdive was here. #Minestom");
displayData.icon = notification.getIcon();
displayData.frameType = notification.getFrameType();
displayData.flags = 0x6;

View File

@ -2,15 +2,10 @@ package net.minestom.server.adventure;
import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Utility methods to convert adventure enums to their packet values.

View File

@ -47,7 +47,10 @@ public class BossBarManager implements BossBar.Listener {
Holder holder = this.getOrCreateHandler(bar);
if (holder.players.add(player.getUuid())) {
player.getPlayerConnection().sendPacket(holder.createAddPacket());
BossBarPacket packet = holder.createAddPacket();
packet.title = MinecraftServer.getSerializationManager().prepare(packet.title, player);
player.getPlayerConnection().sendPacket(packet);
}
}
/**
@ -105,12 +108,27 @@ public class BossBarManager implements BossBar.Listener {
private void updatePlayers(BossBarPacket packet, Set<UUID> players) {
Iterator<UUID> iterator = players.iterator();
// check if we need to translate the bossbar
Component rawTitle = packet.title;
boolean translate = false;
if (packet.action == UPDATE_TITLE || packet.action == ADD) {
Component rootTitle = MinecraftServer.getSerializationManager().prepare(rawTitle, MinecraftServer.getSerializationManager().getDefaultLocale());
if (!rawTitle.equals(rootTitle)) {
translate = true;
}
}
while (iterator.hasNext()) {
Player player = MinecraftServer.getConnectionManager().getPlayer(iterator.next());
if (player == null) {
iterator.remove();
} else {
if (translate) {
packet.title = MinecraftServer.getSerializationManager().prepare(rawTitle, player);
}
player.getPlayerConnection().sendPacket(packet);
}
}
@ -165,9 +183,9 @@ public class BossBarManager implements BossBar.Listener {
@NotNull BossBarPacket createAddPacket() {
return this.createGenericPacket(ADD, packet -> {
packet.title = MinecraftServer.getSerializationManager().serialize(bar.name());
packet.color = AdventurePacketConvertor.getBossBarColorValue(bar.color());
packet.division = AdventurePacketConvertor.getBossBarOverlayValue(bar.overlay());
packet.title = bar.name();
packet.color = bar.color();
packet.overlay = bar.overlay();
packet.health = bar.progress();
packet.flags = AdventurePacketConvertor.getBossBarFlagValue(bar.flags());
});
@ -179,13 +197,13 @@ public class BossBarManager implements BossBar.Listener {
@NotNull BossBarPacket createColorUpdate(@NotNull Color color) {
return this.createGenericPacket(UPDATE_STYLE, packet -> {
packet.color = color.ordinal();
packet.division = AdventurePacketConvertor.getBossBarOverlayValue(bar.overlay());
packet.color = color;
packet.overlay = bar.overlay();
});
}
@NotNull BossBarPacket createTitleUpdate(@NotNull Component title) {
return this.createGenericPacket(UPDATE_TITLE, packet -> packet.title = MinecraftServer.getSerializationManager().serialize(title));
return this.createGenericPacket(UPDATE_TITLE, packet -> packet.title = title);
}
@NotNull BossBarPacket createFlagsUpdate() {
@ -198,8 +216,8 @@ public class BossBarManager implements BossBar.Listener {
@NotNull BossBarPacket createOverlayUpdate(@NotNull Overlay overlay) {
return this.createGenericPacket(UPDATE_STYLE, packet -> {
packet.division = AdventurePacketConvertor.getBossBarOverlayValue(overlay);
packet.color = AdventurePacketConvertor.getBossBarColorValue(bar.color());
packet.overlay = overlay;
packet.color = bar.color();
});
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.adventure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
@ -9,6 +10,15 @@ import java.util.Locale;
*/
public interface Localizable {
/**
* Gets a localizable that returns {@code null} for all calls to {@link #getLocale()}.
*
* @return the empty localizable
*/
static @NotNull Localizable empty() {
return SerializationManager.NULL_LOCALIZABLE;
}
/**
* Gets the locale.
*

View File

@ -0,0 +1,158 @@
package net.minestom.server.adventure;
import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.play.ChatMessagePacket;
import net.minestom.server.network.packet.server.play.PlayerListHeaderAndFooterPacket;
import net.minestom.server.network.packet.server.play.TitlePacket;
import net.minestom.server.utils.PacketUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* Utility class for sending packets with translatable components. All functions in this
* class will send grouped packets if the components do not contain any translatable
* components. In the case that they do, the components are translated and send individually.
*/
public class LocalizablePacketSender {
/**
* Sends a title to many players, sending it as a grouped packet if it does not
* contain translatable elements.
*
* @param players the players
* @param title the title
*/
public static void sendGroupedTitle(@NotNull Collection<Player> players, @NotNull Title title) {
Component preparedTitle = MinecraftServer.getSerializationManager().prepare(title.title(), MinecraftServer.getSerializationManager().getDefaultLocale()),
preparedSubtitle = MinecraftServer.getSerializationManager().prepare(title.subtitle(), MinecraftServer.getSerializationManager().getDefaultLocale());
Collection<TitlePacket> rootPacket = TitlePacket.of(Title.title(preparedTitle, preparedSubtitle, title.times()));
if (title.title().equals(preparedTitle) && title.subtitle().equals(preparedSubtitle)) {
for (TitlePacket packet : rootPacket) {
PacketUtils.sendGroupedPacket(players, packet);
}
} else {
for (Player player : players) {
Collection<TitlePacket> packets;
if (player.getLocale() == null) {
packets = rootPacket;
} else {
packets = TitlePacket.of(Title.title(MinecraftServer.getSerializationManager().prepare(title.title(), player),
MinecraftServer.getSerializationManager().prepare(title.subtitle(), player), title.times()));
}
for (TitlePacket packet : packets) {
player.getPlayerConnection().sendPacket(packet);
}
}
}
}
/**
* Sends an action bar to many players, sending it as a grouped packet if it does not
* contain translatable elements.
*
* @param players the players
* @param component the component
*/
public static void sendGroupedActionBar(@NotNull Collection<Player> players, @NotNull Component component) {
Component preparedComponent = MinecraftServer.getSerializationManager().prepare(component, MinecraftServer.getSerializationManager().getDefaultLocale());
TitlePacket rootPacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, preparedComponent);
if (component.equals(preparedComponent)) {
PacketUtils.sendGroupedPacket(players, rootPacket);
} else {
for (Player player : players) {
TitlePacket packet;
if (player.getLocale() == null) {
packet = rootPacket;
} else {
packet = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, MinecraftServer.getSerializationManager().prepare(component, player));
}
player.getPlayerConnection().sendPacket(packet);
}
}
}
/**
* Sends a player list to many players, sending it as a grouped packet if it does not
* contain translatable elements.
*
* @param players the players
* @param header the header
* @param footer the footer
*/
public static void sendGroupedPlayerList(@NotNull Collection<Player> players, @Nullable Component header, @Nullable Component footer) {
// empty check first
if (header == null) {
header = Component.empty();
}
if (footer == null) {
footer = Component.empty();
}
// now back to the packets
Component preparedHeader = MinecraftServer.getSerializationManager().prepare(header, MinecraftServer.getSerializationManager().getDefaultLocale()),
preparedFooter = MinecraftServer.getSerializationManager().prepare(footer, MinecraftServer.getSerializationManager().getDefaultLocale());
PlayerListHeaderAndFooterPacket rootPacket = new PlayerListHeaderAndFooterPacket(preparedHeader, preparedFooter);
if (header.equals(preparedHeader) && footer.equals(preparedFooter)) {
PacketUtils.sendGroupedPacket(players, rootPacket);
} else {
for (Player player : players) {
PlayerListHeaderAndFooterPacket packet;
if (player.getLocale() == null) {
packet = rootPacket;
} else {
packet = new PlayerListHeaderAndFooterPacket(MinecraftServer.getSerializationManager().prepare(header, player),
MinecraftServer.getSerializationManager().prepare(footer, player));
}
player.getPlayerConnection().sendPacket(packet);
}
}
}
/**
* Sends a message to many players, sending it as a grouped packet if it does not
* contain translatable elements.
*
* @param players the players
* @param source the source of the message
* @param message the message
* @param messageType the type of the message
*/
public static void sendGroupedMessage(@NotNull Collection<Player> players, @NotNull Identity source, @NotNull Component message, @NotNull MessageType messageType) {
ChatMessagePacket.Position position = ChatMessagePacket.Position.fromMessageType(messageType);
Component preparedMessage = MinecraftServer.getSerializationManager().prepare(message, MinecraftServer.getSerializationManager().getDefaultLocale());
ChatMessagePacket rootPacket = new ChatMessagePacket(preparedMessage, position, source.uuid());
if (message.equals(preparedMessage)) {
PacketUtils.sendGroupedPacket(players, rootPacket);
} else {
for (Player player : players) {
ChatMessagePacket packet;
if (player.getLocale() == null) {
packet = rootPacket;
} else {
packet = new ChatMessagePacket(MinecraftServer.getSerializationManager().prepare(message, player), position, source.uuid());
}
player.getPlayerConnection().sendPacket(packet);
}
}
}
}

View File

@ -6,14 +6,10 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.translation.GlobalTranslator;
import net.kyori.adventure.translation.TranslationRegistry;
import net.kyori.adventure.translation.Translator;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Function;
/**
@ -22,11 +18,7 @@ import java.util.function.Function;
* class can be used to change the way text is serialized. For example, a pre-JSON
* implementation of Minestom could change this to the plain component serializer.
* <br><br>
* This manager also provides the ability to wrap the serializer in a renderer that
* performs operations on each component before the final serialization. This can be
* done using {@link #addRenderer(Function)} and {@link #removeRenderer(Function)}.
* <br><br>
* Finally, this manager also performs translation on all messages and the {@code serialize}
* This manager also performs translation on all messages and the {@code serialize}
* method should be used when converting {@link Component}s into strings. This allows for
* messages with {@link TranslatableComponent} to be automatically translated into the locale
* of specific players, or other elements which implement {@link Localizable}. To add your
@ -34,12 +26,13 @@ import java.util.function.Function;
* {@link TranslationRegistry} or your own implementation of {@link Translator}.
*/
public class SerializationManager {
private final Set<Function<Component, Component>> renderers = new CopyOnWriteArraySet<>();
protected static final Localizable NULL_LOCALIZABLE = () -> null;
private Function<Component, String> serializer = component -> GsonComponentSerializer.gson().serialize(component);
private Locale defaultLocale = Locale.US;
/**
* Gets the root serializer that is used to convert Components into Strings.
* Gets the root serializer that is used to convert components into strings.
*
* @return the serializer
*/
@ -48,8 +41,7 @@ public class SerializationManager {
}
/**
* Sets the root serializer that is used to convert Components into Strings. This
* method does not replace any existing renderers set with {@link #addRenderer(Function)}.
* Sets the root serializer that is used to convert components into strings.
*
* @param serializer the serializer
*/
@ -58,9 +50,9 @@ public class SerializationManager {
}
/**
* Gets the default locale used to translate {@link TranslatableComponent} if
* serialized using {@link #serialize(Component)} or when {@link #serialize(Component, Localizable)}
* is used but no translation is found. Note that this is just shorthand for
* Gets the default locale used to translate {@link TranslatableComponent} if, when
* {@link #prepare(Component, Localizable)} is called with a localizable that
* does not have a locale.
*
* @return the default locale
*/
@ -69,9 +61,9 @@ public class SerializationManager {
}
/**
* Sets the default locale used to translate {@link TranslatableComponent} if
* serialized using {@link #serialize(Component)} or when {@link #serialize(Component, Localizable)}
* is used but no translation is found.
* Sets the default locale used to translate {@link TranslatableComponent} if, when
* {@link #prepare(Component, Localizable)} is called with a localizable that
* does not have a locale.
*
* @param defaultLocale the new default locale
*/
@ -79,33 +71,6 @@ public class SerializationManager {
this.defaultLocale = defaultLocale;
}
/**
* Adds a renderer that will be applied to each serializer. The order in which
* each renderer will be applied is arbitrary. If you want control over the order
* of renderers, create a multi-function using {@link Function#andThen(Function)}.
*
* @param renderer the renderer
*/
public void addRenderer(@NotNull Function<Component, Component> renderer) {
this.renderers.add(renderer);
}
/**
* Removes a renderer.
*
* @param renderer the renderer
*/
public void removeRenderer(@NotNull Function<Component, Component> renderer) {
this.renderers.remove(renderer);
}
/**
* Removes all current renderers.
*/
public void clearRenderers() {
this.renderers.clear();
}
/**
* Gets the global translator object used by this manager. This is just shorthand for
* {@link GlobalTranslator#get()}.
@ -117,62 +82,63 @@ public class SerializationManager {
}
/**
* Serializes a component into a String using the current serializer. Any registered
* renderers are applied first, followed by the global translator. Finally, the
* serializer set with {@link #setSerializer(Function)} is used to convert the
* component into a String.
* Prepares a component for serialization. This runs the component through the
* translator for the localizable's locale.
*
* @param component the component
* @param localizable the localizable
*
* @return the serialized string
* @return the prepared component
*/
@Contract("null -> null; !null -> !null")
public String serialize(@Nullable Component component) {
return this.serialize(component, this.defaultLocale);
public @NotNull Component prepare(@NotNull Component component, @NotNull Localizable localizable) {
return GlobalTranslator.renderer().render(component, Objects.requireNonNullElse(localizable.getLocale(), this.getDefaultLocale()));
}
/**
* Serializes a component into a String using the current serializer. Any registered
* renderers are applied first, followed by the global translator. Finally, the
* serializer set with {@link #setSerializer(Function)} is used to convert the
* component into a String.
* Prepares a component for serialization. This runs the component through the
* translator for the locale.
*
* @param component the component
* @param localizable a localizable object used to translate components
* @param locale the locale
*
* @return the serialized string
* @return the prepared component
*/
@Contract("null, _ -> null; !null, _ -> !null")
public String serialize(@Nullable Component component, @NotNull Localizable localizable) {
return this.serialize(component, Objects.requireNonNullElse(localizable.getLocale(), this.defaultLocale));
public @NotNull Component prepare(@NotNull Component component, @NotNull Locale locale) {
return GlobalTranslator.renderer().render(component, locale);
}
/**
* Serializes a component into a String using the current serializer. Any registered
* renderers are applied first, followed by the global translator. Finally, the
* serializer set with {@link #setSerializer(Function)} is used to convert the
* component into a String.
* Serializes a component into a string using {@link #getSerializer()}.
*
* @param component the component
* @param locale the locale used to translate components
*
* @return the serialized string
*/
@Contract("null, _ -> null; !null, _ -> !null")
public String serialize(@Nullable Component component, @NotNull Locale locale) {
if (component == null) {
return null;
}
// apply renderers
for (Function<Component, Component> renderer : this.renderers) {
component = renderer.apply(component);
}
// apply translation
component = GlobalTranslator.render(component, locale);
// apply serialisation
public @NotNull String serialize(@NotNull Component component) {
return this.serializer.apply(component);
}
/**
* Prepares and then serializes a component.
*
* @param component the component
* @param localizable the localisable
*
* @return the string
*/
public String prepareAndSerialize(@NotNull Component component, @NotNull Localizable localizable) {
return this.prepareAndSerialize(component, Objects.requireNonNullElse(localizable.getLocale(), this.getDefaultLocale()));
}
/**
* Prepares and then serializes a component.
*
* @param component the component
* @param locale the locale
*
* @return the string
*/
public String prepareAndSerialize(@NotNull Component component, @NotNull Locale locale) {
return this.serialize(this.prepare(component, locale));
}
}

View File

@ -12,5 +12,9 @@ public enum BarColor {
GREEN,
YELLOW,
PURPLE,
WHITE
WHITE;
public net.kyori.adventure.bossbar.BossBar.Color asAdventureColor() {
return net.kyori.adventure.bossbar.BossBar.Color.valueOf(this.name());
}
}

View File

@ -11,5 +11,9 @@ public enum BarDivision {
SEGMENT_6,
SEGMENT_10,
SEGMENT_12,
SEGMENT_20
SEGMENT_20;
public net.kyori.adventure.bossbar.BossBar.Overlay asAdventureOverlay() {
return net.kyori.adventure.bossbar.BossBar.Overlay.values()[this.ordinal()];
}
}

View File

@ -252,10 +252,10 @@ public class BossBar implements Viewable {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.ADD;
bossBarPacket.title = title.toString();
bossBarPacket.title = title.asComponent();
bossBarPacket.health = progress;
bossBarPacket.color = color.ordinal();
bossBarPacket.division = division.ordinal();
bossBarPacket.color = color.asAdventureColor();
bossBarPacket.overlay = division.asAdventureOverlay();
bossBarPacket.flags = flags;
player.getPlayerConnection().sendPacket(bossBarPacket);
}
@ -278,7 +278,7 @@ public class BossBar implements Viewable {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.UPDATE_TITLE;
bossBarPacket.title = title.toString();
bossBarPacket.title = title.asComponent();
sendPacketToViewers(bossBarPacket);
}
@ -294,7 +294,7 @@ public class BossBar implements Viewable {
BossBarPacket bossBarPacket = new BossBarPacket();
bossBarPacket.uuid = uuid;
bossBarPacket.action = BossBarPacket.Action.UPDATE_STYLE;
bossBarPacket.color = color.ordinal();
bossBarPacket.color = color.asAdventureColor();
sendPacketToViewers(bossBarPacket);
}
}

View File

@ -20,7 +20,6 @@ import net.minestom.server.chat.ChatParser;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.chat.RichMessage;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.command.CommandManager;
import net.minestom.server.command.CommandSender;
@ -507,7 +506,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
// #buildDeathScreenText can return null, check here
if (deathText != null) {
CombatEventPacket deathPacket = CombatEventPacket.death(this, null, MinecraftServer.getSerializationManager().serialize(deathText, this));
CombatEventPacket deathPacket = CombatEventPacket.death(this, null, MinecraftServer.getSerializationManager().prepare(deathText, this));
playerConnection.sendPacket(deathPacket);
}
@ -805,7 +804,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override
public void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) {
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(MinecraftServer.getSerializationManager().serialize(message, this), ChatMessagePacket.Position.fromMessageType(type), source.uuid());
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(MinecraftServer.getSerializationManager().prepare(message, this), ChatMessagePacket.Position.fromMessageType(type), source.uuid());
playerConnection.sendPacket(chatMessagePacket);
}
@ -1008,9 +1007,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override
public void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) {
PlayerListHeaderAndFooterPacket packet = new PlayerListHeaderAndFooterPacket();
packet.header = MinecraftServer.getSerializationManager().serialize(header, this);
packet.footer = MinecraftServer.getSerializationManager().serialize(footer, this);
PlayerListHeaderAndFooterPacket packet
= new PlayerListHeaderAndFooterPacket(MinecraftServer.getSerializationManager().prepare(header, this), MinecraftServer.getSerializationManager().prepare(footer, this));
playerConnection.sendPacket(packet);
}
@ -1025,7 +1023,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
*/
@Deprecated
private void sendTitle(@NotNull JsonMessage text, @NotNull TitlePacket.Action action) {
TitlePacket titlePacket = new TitlePacket(action, text.toString());
TitlePacket titlePacket = new TitlePacket(action, text.asComponent());
playerConnection.sendPacket(titlePacket);
}
@ -1084,14 +1082,18 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
@Override
public void showTitle(@NotNull Title title) {
for (TitlePacket titlePacket : TitlePacket.of(title)) {
Component preparedTitle = MinecraftServer.getSerializationManager().prepare(title.title(), this),
preparedSubtitle = MinecraftServer.getSerializationManager().prepare(title.subtitle(), this);
Collection<TitlePacket> packet = TitlePacket.of(Title.title(preparedTitle, preparedSubtitle, title.times()));
for (TitlePacket titlePacket : packet) {
playerConnection.sendPacket(titlePacket);
}
}
@Override
public void sendActionBar(@NotNull Component message) {
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, MinecraftServer.getSerializationManager().serialize(message, this));
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, MinecraftServer.getSerializationManager().prepare(message, this));
playerConnection.sendPacket(titlePacket);
}
@ -1175,7 +1177,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
public void openBook(@NotNull Book book) {
// make the book
ItemStack writtenBook = new ItemStack(Material.WRITTEN_BOOK, (byte) 1);
writtenBook.setItemMeta(WrittenBookMeta.fromAdventure(book));
writtenBook.setItemMeta(WrittenBookMeta.fromAdventure(book, this));
// Set book in offhand
SetSlotPacket setBookPacket = new SetSlotPacket();
@ -1341,7 +1343,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
this.displayName = displayName;
PlayerInfoPacket infoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.UPDATE_DISPLAY_NAME);
infoPacket.playerInfos.add(new PlayerInfoPacket.UpdateDisplayName(getUuid(), MinecraftServer.getSerializationManager().serialize(displayName)));
infoPacket.playerInfos.add(new PlayerInfoPacket.UpdateDisplayName(getUuid(), displayName));
sendPacketToViewersAndSelf(infoPacket);
}
@ -1920,9 +1922,9 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
// Packet type depends on the current player connection state
final ServerPacket disconnectPacket;
if (connectionState == ConnectionState.LOGIN) {
disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(component, this));
disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().prepare(component, this));
} else {
disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().serialize(component, this));
disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().prepare(component, this));
}
if (playerConnection instanceof NettyPlayerConnection) {
@ -2547,7 +2549,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable {
PlayerInfoPacket.AddPlayer addPlayer =
new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), getGameMode(), getLatency());
addPlayer.displayName = MinecraftServer.getSerializationManager().serialize(displayName);
addPlayer.displayName = displayName;
// Skin support
if (skin != null) {

View File

@ -3,9 +3,7 @@ package net.minestom.server.item.metadata;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatParser;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.adventure.Localizable;
import org.jetbrains.annotations.NotNull;
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
import org.jglrxavpok.hephaistos.nbt.NBTList;
@ -202,15 +200,17 @@ public class WrittenBookMeta extends ItemMeta {
* resolved and the generation will default to {@link WrittenBookGeneration#ORIGINAL}.
*
* @param book the book
* @param localizable who the book is for
*
* @return the meta
*/
public static @NotNull WrittenBookMeta fromAdventure(@NotNull Book book) {
public static @NotNull WrittenBookMeta fromAdventure(@NotNull Book book, @NotNull Localizable localizable) {
// make the book
WrittenBookMeta meta = new WrittenBookMeta();
meta.resolved = false;
meta.generation = WrittenBookGeneration.ORIGINAL;
meta.author = MinecraftServer.getSerializationManager().serialize(book.author());
meta.title = MinecraftServer.getSerializationManager().serialize(book.title());
meta.author = MinecraftServer.getSerializationManager().prepareAndSerialize(book.author(), localizable);
meta.title = MinecraftServer.getSerializationManager().prepareAndSerialize(book.title(), localizable);
meta.pages = new ArrayList<>();
for (Component page : book.pages()) {

View File

@ -4,9 +4,11 @@ import io.netty.channel.Channel;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.LocalizablePacketSender;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Player;
import net.minestom.server.entity.fakeplayer.FakePlayer;
@ -17,12 +19,10 @@ import net.minestom.server.listener.manager.ClientPacketConsumer;
import net.minestom.server.listener.manager.ServerPacketConsumer;
import net.minestom.server.network.packet.client.login.LoginStartPacket;
import net.minestom.server.network.packet.server.login.LoginSuccessPacket;
import net.minestom.server.network.packet.server.play.ChatMessagePacket;
import net.minestom.server.network.packet.server.play.DisconnectPacket;
import net.minestom.server.network.packet.server.play.KeepAlivePacket;
import net.minestom.server.network.player.NettyPlayerConnection;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.async.AsyncUtils;
import net.minestom.server.utils.callback.validator.PlayerValidator;
import net.minestom.server.utils.validate.Check;
@ -156,7 +156,7 @@ public final class ConnectionManager implements ForwardingAudience {
if (!recipients.isEmpty()) {
final String jsonText = jsonMessage.toString();
broadcastJson(jsonText, recipients);
LocalizablePacketSender.sendGroupedMessage(recipients, Identity.nil(), jsonMessage.asComponent(), MessageType.CHAT);
}
}
@ -168,13 +168,7 @@ public final class ConnectionManager implements ForwardingAudience {
*/
@Deprecated
public void broadcastMessage(@NotNull JsonMessage jsonMessage) {
broadcastMessage(jsonMessage, null);
}
private void broadcastJson(@NotNull String json, @NotNull Collection<Player> recipients) {
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(json, ChatMessagePacket.Position.SYSTEM_MESSAGE);
PacketUtils.sendGroupedPacket(recipients, chatMessagePacket);
this.sendMessage(jsonMessage);
}
private Collection<Player> getRecipients(@Nullable PlayerValidator condition) {
@ -491,10 +485,11 @@ public final class ConnectionManager implements ForwardingAudience {
* Shutdowns the connection manager by kicking all the currently connected players.
*/
public void shutdown() {
DisconnectPacket disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().serialize(shutdownText));
DisconnectPacket disconnectPacket = new DisconnectPacket(shutdownText);
for (Player player : getOnlinePlayers()) {
final PlayerConnection playerConnection = player.getPlayerConnection();
if (playerConnection instanceof NettyPlayerConnection) {
disconnectPacket.message = MinecraftServer.getSerializationManager().prepare(disconnectPacket.message, player);
final NettyPlayerConnection nettyPlayerConnection = (NettyPlayerConnection) playerConnection;
final Channel channel = nettyPlayerConnection.getChannel();
channel.writeAndFlush(disconnectPacket);

View File

@ -70,7 +70,7 @@ public class HandshakePacket implements ClientPreplayPacket {
nettyPlayerConnection.UNSAFE_setBungeeSkin(playerSkin);
} else {
nettyPlayerConnection.sendPacket(new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(INVALID_BUNGEE_FORWARDING)));
nettyPlayerConnection.sendPacket(new LoginDisconnectPacket(INVALID_BUNGEE_FORWARDING));
nettyPlayerConnection.disconnect();
return;
}
@ -94,7 +94,7 @@ public class HandshakePacket implements ClientPreplayPacket {
}
} else {
// Incorrect client version
connection.sendPacket(new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(INVALID_VERSION_TEXT)));
connection.sendPacket(new LoginDisconnectPacket(INVALID_VERSION_TEXT));
connection.disconnect();
}
break;

View File

@ -80,7 +80,7 @@ public class LoginPluginResponsePacket implements ClientPreplayPacket {
Player player = CONNECTION_MANAGER.startPlayState(connection, uuid, username, true);
player.setSkin(playerSkin);
} else {
LoginDisconnectPacket disconnectPacket = new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(INVALID_PROXY_RESPONSE));
LoginDisconnectPacket disconnectPacket = new LoginDisconnectPacket(INVALID_PROXY_RESPONSE);
nettyPlayerConnection.sendPacket(disconnectPacket);
}

View File

@ -3,8 +3,6 @@ package net.minestom.server.network.packet.client.login;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.entity.Player;
import net.minestom.server.extras.MojangAuth;
import net.minestom.server.extras.bungee.BungeeCordProxy;
@ -74,7 +72,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
if (MojangAuth.isEnabled() && isNettyClient) {
// Mojang auth
if (CONNECTION_MANAGER.getPlayer(username) != null) {
connection.sendPacket(new LoginDisconnectPacket(MinecraftServer.getSerializationManager().serialize(ALREADY_CONNECTED)));
connection.sendPacket(new LoginDisconnectPacket(ALREADY_CONNECTED));
connection.disconnect();
return;
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.network.packet.server.login;
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;
@ -8,23 +9,23 @@ import org.jetbrains.annotations.NotNull;
public class LoginDisconnectPacket implements ServerPacket {
private final String kickMessage; // JSON text
private final Component kickMessage; // JSON text
public LoginDisconnectPacket(@NotNull String kickMessage) {
public LoginDisconnectPacket(@NotNull Component kickMessage) {
this.kickMessage = kickMessage;
}
/**
* @deprecated Use {@link #LoginDisconnectPacket(String)}
* @deprecated Use {@link #LoginDisconnectPacket(Component)}
*/
@Deprecated
public LoginDisconnectPacket(@NotNull JsonMessage jsonKickMessage) {
this(jsonKickMessage.toString());
this(jsonKickMessage.asComponent());
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(kickMessage);
writer.writeComponent(kickMessage);
}
@Override

View File

@ -1,7 +1,7 @@
package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.advancements.FrameType;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
@ -84,8 +84,8 @@ public class AdvancementsPacket implements ServerPacket {
}
public static class DisplayData implements Writeable {
public String title; // Only text
public String description; // Only text
public Component title; // Only text
public Component description; // Only text
public ItemStack icon;
public FrameType frameType;
public int flags;
@ -93,19 +93,10 @@ public class AdvancementsPacket implements ServerPacket {
public float x;
public float y;
/**
* @deprecated Use {@link #title}
*/
public @Deprecated JsonMessage titleJson; // Only text
/**
* @deprecated Use {@link #description}
*/
public @Deprecated JsonMessage descriptionJson; // Only text
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(titleJson != null ? titleJson.toString() : title);
writer.writeSizedString(descriptionJson != null ? descriptionJson.toString() : description);
writer.writeComponent(title);
writer.writeComponent(description);
writer.writeItemStack(icon);
writer.writeVarInt(frameType.ordinal());
writer.writeInt(flags);

View File

@ -1,8 +1,8 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.bossbar.BarColor;
import net.minestom.server.bossbar.BarDivision;
import net.minestom.server.chat.JsonMessage;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import net.minestom.server.adventure.AdventurePacketConvertor;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryWriter;
@ -15,25 +15,12 @@ public class BossBarPacket implements ServerPacket {
public UUID uuid;
public Action action;
public String title; // Only text
public Component title; // Only text
public float health;
public int color;
public int division;
public BossBar.Color color;
public BossBar.Overlay overlay;
public byte flags;
/**
* @deprecated Use {@link #title}
*/
public @Deprecated JsonMessage titleJson;
/**
* @deprecated Use {@link #color}
*/
public @Deprecated BarColor colorOld;
/**
* @deprecated Use {@link #division}
*/
public @Deprecated BarDivision divisionOld;
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeUuid(uuid);
@ -41,10 +28,10 @@ public class BossBarPacket implements ServerPacket {
switch (action) {
case ADD:
writer.writeSizedString(titleJson != null ? titleJson.toString() : title);
writer.writeComponent(title);
writer.writeFloat(health);
writer.writeVarInt(colorOld != null ? colorOld.ordinal() : color);
writer.writeVarInt(divisionOld != null ? divisionOld.ordinal() : division);
writer.writeVarInt(AdventurePacketConvertor.getBossBarColorValue(color));
writer.writeVarInt(AdventurePacketConvertor.getBossBarOverlayValue(overlay));
writer.writeByte(flags);
break;
case REMOVE:
@ -54,11 +41,11 @@ public class BossBarPacket implements ServerPacket {
writer.writeFloat(health);
break;
case UPDATE_TITLE:
writer.writeSizedString(titleJson != null ? titleJson.toString() : title);
writer.writeComponent(title);
break;
case UPDATE_STYLE:
writer.writeVarInt(colorOld != null ? colorOld.ordinal() : color);
writer.writeVarInt(divisionOld != null ? divisionOld.ordinal() : division);
writer.writeVarInt(AdventurePacketConvertor.getBossBarColorValue(color));
writer.writeVarInt(AdventurePacketConvertor.getBossBarOverlayValue(overlay));
break;
case UPDATE_FLAGS:
writer.writeByte(flags);

View File

@ -1,7 +1,7 @@
package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.audience.MessageType;
import net.minestom.server.chat.JsonMessage;
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;
@ -16,28 +16,23 @@ import java.util.UUID;
public class ChatMessagePacket implements ServerPacket {
private static final UUID NULL_UUID = new UUID(0, 0);
public String message;
public Component message;
public Position position;
public UUID uuid;
/**
* @deprecated Use {@link #message}
*/
public @Deprecated JsonMessage jsonMessage;
public ChatMessagePacket(String jsonMessage, Position position, UUID uuid) {
this.message = jsonMessage;
public ChatMessagePacket(Component message, Position position, UUID uuid) {
this.message = message;
this.position = position;
this.uuid = uuid;
}
public ChatMessagePacket(String jsonMessage, Position position) {
this(jsonMessage, position, NULL_UUID);
public ChatMessagePacket(Component message, Position position) {
this(message, position, NULL_UUID);
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(jsonMessage != null ? jsonMessage.toString() : message);
writer.writeComponent(message);
writer.writeByte((byte) position.ordinal());
writer.writeUuid(uuid);
}

View File

@ -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.entity.Entity;
import net.minestom.server.entity.Player;
@ -8,8 +9,6 @@ import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
/**
* Packet sent during combat to a {@link Player}.
* Only death is supported for the moment (other events are ignored anyway as of 1.15.2)
@ -20,7 +19,7 @@ public class CombatEventPacket implements ServerPacket {
private int duration;
private int opponent;
private int playerID;
private String deathMessage;
private Component deathMessage;
private CombatEventPacket() {
}
@ -40,14 +39,14 @@ public class CombatEventPacket implements ServerPacket {
}
/**
* @deprecated Use {@link #death(Player, Entity, String)}
* @deprecated Use {@link #death(Player, Entity, Component)}
*/
@Deprecated
public static CombatEventPacket death(Player player, Entity killer, JsonMessage message) {
return death(player, killer, message.toString());
return death(player, killer, message.asComponent());
}
public static CombatEventPacket death(Player player, Entity killer, String message) {
public static CombatEventPacket death(Player player, Entity killer, Component message) {
CombatEventPacket packet = new CombatEventPacket();
packet.type = EventType.DEATH;
packet.playerID = player.getEntityId();
@ -72,7 +71,7 @@ public class CombatEventPacket implements ServerPacket {
case DEATH:
writer.writeVarInt(playerID);
writer.writeInt(opponent);
writer.writeSizedString(deathMessage);
writer.writeComponent(deathMessage);
break;
}
}

View File

@ -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,32 +8,27 @@ import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull;
public class DisconnectPacket implements ServerPacket {
public String message;
public Component message;
/**
* @deprecated Use {@link #message}
*/
@Deprecated public JsonMessage messageJson;
/**
* Creates a new disconnect packet with a given string.
* Creates a new disconnect packet with a given message.
* @param message the message
*/
public DisconnectPacket(@NotNull String message) {
public DisconnectPacket(@NotNull Component message) {
this.message = message;
}
/**
* @deprecated Use {@link #DisconnectPacket(String)}
* @deprecated Use {@link #DisconnectPacket(Component)}
*/
@Deprecated
public DisconnectPacket(@NotNull JsonMessage message){
this(message.toString());
this(message.asComponent());
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(messageJson != null ? messageJson.toString() : message);
writer.writeComponent(message);
}
@Override

View File

@ -1,6 +1,6 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.chat.JsonMessage;
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;
@ -63,13 +63,7 @@ public class MapDataPacket implements ServerPacket {
public int type;
public byte x, z;
public byte direction;
public String displayName;
/**
* @deprecated Use {@link #displayName}
*/
@Deprecated
public JsonMessage displayNameJson; // Only text
public Component displayName;
private void write(BinaryWriter writer) {
writer.writeVarInt(type);
@ -77,10 +71,10 @@ public class MapDataPacket implements ServerPacket {
writer.writeByte(z);
writer.writeByte(direction);
final boolean hasDisplayName = displayName != null || displayNameJson != null;
final boolean hasDisplayName = displayName != null;
writer.writeBoolean(hasDisplayName);
if (hasDisplayName) {
writer.writeSizedString(displayNameJson != null ? displayNameJson.toString() : displayName);
writer.writeComponent(displayName);
}
}

View File

@ -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.entity.GameMode;
import net.minestom.server.network.packet.server.ServerPacket;
@ -75,12 +76,7 @@ public class PlayerInfoPacket implements ServerPacket {
public List<Property> properties;
public GameMode gameMode;
public int ping;
public String displayName;
/**
* @deprecated Use {@link #displayName}
*/
@Deprecated public JsonMessage displayNameJson; // Only text
public Component displayName;
public AddPlayer(UUID uuid, String name, GameMode gameMode, int ping) {
super(uuid);
@ -100,10 +96,10 @@ public class PlayerInfoPacket implements ServerPacket {
writer.writeVarInt(gameMode.getId());
writer.writeVarInt(ping);
final boolean hasDisplayName = displayName != null || displayNameJson != null;
final boolean hasDisplayName = displayName != null;
writer.writeBoolean(hasDisplayName);
if (hasDisplayName)
writer.writeSizedString(displayNameJson != null ? displayNameJson.toString() : displayName);
writer.writeComponent(displayName);
}
public static class Property {
@ -166,22 +162,17 @@ public class PlayerInfoPacket implements ServerPacket {
public static class UpdateDisplayName extends PlayerInfo {
public String displayName;
public Component displayName;
/**
* @deprecated Use {@link #displayName}
*/
@Deprecated public JsonMessage displayNameJson; // Only text
/**
* @deprecated Use {@link #UpdateDisplayName(UUID, String)}
* @deprecated Use {@link #UpdateDisplayName(UUID, Component)}
*/
@Deprecated
public UpdateDisplayName(UUID uuid, JsonMessage displayName) {
this(uuid, displayName.toString());
this(uuid, displayName.asComponent());
}
public UpdateDisplayName(UUID uuid, String displayName) {
public UpdateDisplayName(UUID uuid, Component displayName) {
super(uuid);
this.displayName = displayName;
}
@ -191,7 +182,7 @@ public class PlayerInfoPacket implements ServerPacket {
final boolean hasDisplayName = displayName != null;
writer.writeBoolean(hasDisplayName);
if (hasDisplayName)
writer.writeSizedString(displayNameJson != null ? displayNameJson.toString() : displayName);
writer.writeComponent(displayName);
}
}

View File

@ -1,36 +1,27 @@
package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
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.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class PlayerListHeaderAndFooterPacket implements ServerPacket {
private static final String EMPTY_COMPONENT = GsonComponentSerializer.gson().serialize(Component.empty());
public Component header;
public Component footer;
public String header;
public String footer;
/**
* @deprecated Use {@link #header}
*/
@Deprecated public JsonMessage headerJson;
/**
@deprecated Use {@link #footer}
*/
@Deprecated public JsonMessage footerJson;
public PlayerListHeaderAndFooterPacket(@Nullable Component header, @Nullable Component footer) {
this.header = header;
this.footer = footer;
}
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(headerJson != null ? headerJson.toString() : Objects.requireNonNullElse(header, EMPTY_COMPONENT));
writer.writeSizedString(footerJson != null ? footerJson.toString() : Objects.requireNonNullElse(footer, EMPTY_COMPONENT));
writer.writeComponent(Objects.requireNonNullElse(header, Component.empty()));
writer.writeComponent(Objects.requireNonNullElse(footer, Component.empty()));
}
@Override

View File

@ -1,6 +1,6 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.chat.JsonMessage;
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;
@ -21,25 +21,19 @@ public class ScoreboardObjectivePacket implements ServerPacket {
/**
* The text to be displayed for the score
*/
public String objectiveValue; // Only text
public Component objectiveValue; // Only text
/**
* The type how the score is displayed
*/
public Type type;
/**
* @deprecated Use {@link #objectiveValue}
*/
@Deprecated
public JsonMessage objectiveValueJson;
@Override
public void write(@NotNull BinaryWriter writer) {
writer.writeSizedString(objectiveName);
writer.writeByte(mode);
if (mode == 0 || mode == 2) {
writer.writeSizedString(objectiveValueJson != null ? objectiveValueJson.toString() : objectiveValue);
writer.writeComponent(objectiveValue);
writer.writeVarInt(type.ordinal());
}
}

View File

@ -1,6 +1,6 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.chat.JsonMessage;
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;
@ -24,7 +24,7 @@ public class TabCompletePacket implements ServerPacket {
writer.writeSizedString(match.match);
writer.writeBoolean(match.hasTooltip);
if (match.hasTooltip)
writer.writeSizedString(match.tooltipJson != null ? match.tooltipJson.toString() : match.tooltip);
writer.writeComponent(match.tooltip);
}
}
@ -36,12 +36,7 @@ public class TabCompletePacket implements ServerPacket {
public static class Match {
public String match;
public boolean hasTooltip;
public String tooltip;
/**
* @deprecated Use {@link #tooltip}
*/
@Deprecated public String tooltipJson;
public Component tooltip;
}
}

View File

@ -1,6 +1,6 @@
package net.minestom.server.network.packet.server.play;
import net.minestom.server.chat.JsonMessage;
import net.kyori.adventure.text.Component;
import net.minestom.server.color.TeamColor;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
@ -24,7 +24,7 @@ public class TeamsPacket implements ServerPacket {
/**
* The display name for the team
*/
public String teamDisplayName;
public Component teamDisplayName;
/**
* The friendly flags to
*/
@ -44,34 +44,16 @@ public class TeamsPacket implements ServerPacket {
/**
* The prefix of the team
*/
public String teamPrefix;
public Component teamPrefix;
/**
* The suffix of the team
*/
public String teamSuffix;
public Component teamSuffix;
/**
* An array with all entities in the team
*/
public String[] entities;
/**
* @deprecated Use {@link #teamColor}
*/
@Deprecated public int teamColorOld = -1;
/**
* @deprecated Use {@link #teamDisplayName}
*/
@Deprecated public JsonMessage teamDisplayNameJson;
/**
@deprecated Use {@link #teamPrefix}
*/
@Deprecated public JsonMessage teamPrefixJson;
/**
@deprecated Use {@link #teamSuffix}
*/
@Deprecated public JsonMessage teamSuffixJson;
/**
* Writes data into the {@link BinaryWriter}
*
@ -85,13 +67,13 @@ public class TeamsPacket implements ServerPacket {
switch (action) {
case CREATE_TEAM:
case UPDATE_TEAM_INFO:
writer.writeSizedString(this.teamDisplayNameJson != null ? this.teamDisplayNameJson.toString() : this.teamDisplayName);
writer.writeComponent(this.teamDisplayName);
writer.writeByte(this.friendlyFlags);
writer.writeSizedString(this.nameTagVisibility.getIdentifier());
writer.writeSizedString(this.collisionRule.getIdentifier());
writer.writeVarInt(this.teamColorOld != -1 ? this.teamColorOld : this.teamColor.getId());
writer.writeSizedString(this.teamPrefixJson != null ? this.teamPrefixJson.toString() : this.teamPrefix);
writer.writeSizedString(this.teamSuffixJson != null ? this.teamSuffixJson.toString() : this.teamSuffix);
writer.writeVarInt(this.teamColor.getId());
writer.writeComponent(this.teamPrefix);
writer.writeComponent(this.teamSuffix);
break;
case REMOVE_TEAM:

View File

@ -1,7 +1,7 @@
package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import net.minestom.server.MinecraftServer;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.TickUtils;
@ -19,21 +19,21 @@ public class TitlePacket implements ServerPacket {
public Action action;
public String payload;
public Component payload;
public int fadeIn;
public int stay;
public int fadeOut;
/**
* Constructs a new title packet from an action that can take a string argument.
* Constructs a new title packet from an action that can take a component 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) {
public TitlePacket(@NotNull Action action, @NotNull Component payload) {
Validate.isTrue(action == SET_TITLE || action == SET_SUBTITLE || action == SET_ACTION_BAR, "Invalid action type");
this.action = action;
this.payload = payload;
@ -72,7 +72,7 @@ public class TitlePacket implements ServerPacket {
case SET_TITLE:
case SET_SUBTITLE:
case SET_ACTION_BAR:
writer.writeSizedString(payload);
writer.writeComponent(payload);
break;
case SET_TIMES_AND_DISPLAY:
writer.writeInt(fadeIn);
@ -109,8 +109,8 @@ public class TitlePacket implements ServerPacket {
List<TitlePacket> packets = new ArrayList<>(4);
// base packets
packets.add(new TitlePacket(SET_TITLE, MinecraftServer.getSerializationManager().serialize(title.title())));
packets.add(new TitlePacket(SET_SUBTITLE, MinecraftServer.getSerializationManager().serialize(title.subtitle())));
packets.add(new TitlePacket(SET_TITLE, title.title()));
packets.add(new TitlePacket(SET_SUBTITLE, title.subtitle()));
// times packet
Title.Times times = title.times();

View File

@ -3,7 +3,6 @@ package net.minestom.server.scoreboard;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.Viewable;
import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
@ -42,7 +41,7 @@ public interface Scoreboard extends Viewable, ForwardingAudience {
final ScoreboardObjectivePacket packet = new ScoreboardObjectivePacket();
packet.objectiveName = this.getObjectiveName();
packet.mode = 0; // Create Scoreboard
packet.objectiveValue = MinecraftServer.getSerializationManager().serialize(value);
packet.objectiveValue = value;
packet.type = type;
return packet;

View File

@ -409,13 +409,13 @@ public class Team implements ForwardingAudience {
TeamsPacket teamsCreationPacket = new TeamsPacket();
teamsCreationPacket.teamName = teamName;
teamsCreationPacket.action = TeamsPacket.Action.CREATE_TEAM;
teamsCreationPacket.teamDisplayName = MinecraftServer.getSerializationManager().serialize(this.teamDisplayName);
teamsCreationPacket.teamDisplayName = this.teamDisplayName;
teamsCreationPacket.friendlyFlags = this.friendlyFlags;
teamsCreationPacket.nameTagVisibility = this.nameTagVisibility;
teamsCreationPacket.collisionRule = this.collisionRule;
teamsCreationPacket.teamColor = this.teamColor;
teamsCreationPacket.teamPrefix = MinecraftServer.getSerializationManager().serialize(this.prefix);
teamsCreationPacket.teamSuffix = MinecraftServer.getSerializationManager().serialize(this.suffix);
teamsCreationPacket.teamPrefix = this.prefix;
teamsCreationPacket.teamSuffix = this.suffix;
teamsCreationPacket.entities = this.members.toArray(new String[0]);
return teamsCreationPacket;
@ -562,13 +562,13 @@ public class Team implements ForwardingAudience {
final TeamsPacket updatePacket = new TeamsPacket();
updatePacket.teamName = this.teamName;
updatePacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
updatePacket.teamDisplayName = MinecraftServer.getSerializationManager().serialize(this.teamDisplayName);
updatePacket.teamDisplayName = this.teamDisplayName;
updatePacket.friendlyFlags = this.friendlyFlags;
updatePacket.nameTagVisibility = this.nameTagVisibility;
updatePacket.collisionRule = this.collisionRule;
updatePacket.teamColor = this.teamColor;
updatePacket.teamPrefix = MinecraftServer.getSerializationManager().serialize(this.prefix);
updatePacket.teamSuffix = MinecraftServer.getSerializationManager().serialize(this.suffix);
updatePacket.teamPrefix = this.prefix;
updatePacket.teamSuffix = this.suffix;
PacketUtils.sendGroupedPacket(MinecraftServer.getConnectionManager().getOnlinePlayers(), updatePacket);
}

View File

@ -2,6 +2,7 @@ package net.minestom.server.utils.binary;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.item.ItemStack;
import net.minestom.server.utils.BlockPosition;
@ -61,6 +62,15 @@ public class BinaryWriter extends OutputStream {
this.buffer = Unpooled.buffer();
}
/**
* Writes a component to the buffer as a sized string.
*
* @param component the component
*/
public void writeComponent(Component component) {
this.writeSizedString(MinecraftServer.getSerializationManager().serialize(component));
}
/**
* Writes a single boolean to the buffer.
*