mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-08 09:27:58 +01:00
Simplify component translation
This commit is contained in:
parent
c40139349b
commit
52ce8027f2
@ -47,10 +47,7 @@ public class BossBarManager implements BossBar.Listener {
|
||||
Holder holder = this.getOrCreateHandler(bar);
|
||||
|
||||
if (holder.players.add(player.getUuid())) {
|
||||
BossBarPacket packet = holder.createAddPacket();
|
||||
packet.title = MinecraftServer.getSerializationManager().prepare(packet.title, player);
|
||||
|
||||
player.getPlayerConnection().sendPacket(packet);
|
||||
player.getPlayerConnection().sendPacket(holder.createAddPacket());
|
||||
}
|
||||
}
|
||||
/**
|
||||
@ -108,27 +105,12 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
package net.minestom.server.adventure;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Represents an object that holds some amount of components.
|
||||
* @param <T> the holding class
|
||||
*/
|
||||
public interface ComponentHolder<T> {
|
||||
|
||||
/**
|
||||
* Gets the components held by this object.
|
||||
* @return the components
|
||||
*/
|
||||
@NotNull Collection<Component> components();
|
||||
|
||||
/**
|
||||
* Returns a copy of this object. For each component this object holds, the operator
|
||||
* is applied to the copy before returning.
|
||||
* @param operator the operator
|
||||
* @return the copy
|
||||
*/
|
||||
@NotNull T copyWithOperator(@NotNull UnaryOperator<Component> operator);
|
||||
|
||||
/**
|
||||
* Visits each component held by this object.
|
||||
* @param visitor the visitor
|
||||
*/
|
||||
default void visitComponents(@NotNull Consumer<Component> visitor) {
|
||||
for (Component component : this.components()) {
|
||||
visitor.accept(component);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import net.kyori.adventure.translation.TranslationRegistry;
|
||||
import net.kyori.adventure.translation.Translator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
@ -51,7 +52,7 @@ public class SerializationManager {
|
||||
|
||||
/**
|
||||
* Gets the default locale used to translate {@link TranslatableComponent} if, when
|
||||
* {@link #prepare(Component, Localizable)} is called with a localizable that
|
||||
* {@link #translate(Component, Localizable)} is called with a localizable that
|
||||
* does not have a locale.
|
||||
*
|
||||
* @return the default locale
|
||||
@ -62,7 +63,7 @@ public class SerializationManager {
|
||||
|
||||
/**
|
||||
* Sets the default locale used to translate {@link TranslatableComponent} if, when
|
||||
* {@link #prepare(Component, Localizable)} is called with a localizable that
|
||||
* {@link #translate(Component, Localizable)} is called with a localizable that
|
||||
* does not have a locale.
|
||||
*
|
||||
* @param defaultLocale the new default locale
|
||||
@ -90,7 +91,7 @@ public class SerializationManager {
|
||||
*
|
||||
* @return the prepared component
|
||||
*/
|
||||
public @NotNull Component prepare(@NotNull Component component, @NotNull Localizable localizable) {
|
||||
public @NotNull Component translate(@NotNull Component component, @NotNull Localizable localizable) {
|
||||
return GlobalTranslator.renderer().render(component, Objects.requireNonNullElse(localizable.getLocale(), this.getDefaultLocale()));
|
||||
}
|
||||
|
||||
@ -103,7 +104,7 @@ public class SerializationManager {
|
||||
*
|
||||
* @return the prepared component
|
||||
*/
|
||||
public @NotNull Component prepare(@NotNull Component component, @NotNull Locale locale) {
|
||||
public @NotNull Component translate(@NotNull Component component, @NotNull Locale locale) {
|
||||
return GlobalTranslator.renderer().render(component, locale);
|
||||
}
|
||||
|
||||
@ -126,8 +127,8 @@ public class SerializationManager {
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public String prepareAndSerialize(@NotNull Component component, @NotNull Localizable localizable) {
|
||||
return this.prepareAndSerialize(component, Objects.requireNonNullElse(localizable.getLocale(), this.getDefaultLocale()));
|
||||
public String translateAndSerialize(@NotNull Component component, @NotNull Localizable localizable) {
|
||||
return this.translateAndSerialize(component, Objects.requireNonNullElse(localizable.getLocale(), this.getDefaultLocale()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,7 +139,35 @@ public class SerializationManager {
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public String prepareAndSerialize(@NotNull Component component, @NotNull Locale locale) {
|
||||
return this.serialize(this.prepare(component, locale));
|
||||
public String translateAndSerialize(@NotNull Component component, @NotNull Locale locale) {
|
||||
return this.serialize(this.translate(component, locale));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a component can be translated server-side. This is done by running the
|
||||
* component through the translator and seeing if the translated component is equal
|
||||
* to the non translated component.
|
||||
* @param component the component
|
||||
* @return {@code true} if the component can be translated server-side,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public boolean isTranslatable(@NotNull Component component) {
|
||||
return !component.equals(this.translate(component, this.getDefaultLocale()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any of a series of components are translatable server-side.
|
||||
* @param components the components
|
||||
* @return {@code true} if any of the components can be translated server-side,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public boolean areAnyTranslatable(@NotNull Collection<Component> components) {
|
||||
for (Component component : components) {
|
||||
if (this.isTranslatable(component)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -508,7 +508,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().prepare(deathText, this));
|
||||
CombatEventPacket deathPacket = CombatEventPacket.death(this, null, deathText);
|
||||
playerConnection.sendPacket(deathPacket);
|
||||
}
|
||||
|
||||
@ -806,7 +806,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().prepare(message, this), ChatMessagePacket.Position.fromMessageType(type), source.uuid());
|
||||
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(message, ChatMessagePacket.Position.fromMessageType(type), source.uuid());
|
||||
playerConnection.sendPacket(chatMessagePacket);
|
||||
}
|
||||
|
||||
@ -1009,8 +1009,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
@Override
|
||||
public void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) {
|
||||
PlayerListHeaderAndFooterPacket packet
|
||||
= new PlayerListHeaderAndFooterPacket(MinecraftServer.getSerializationManager().prepare(header, this), MinecraftServer.getSerializationManager().prepare(footer, this));
|
||||
PlayerListHeaderAndFooterPacket packet = new PlayerListHeaderAndFooterPacket(header, footer);
|
||||
playerConnection.sendPacket(packet);
|
||||
}
|
||||
|
||||
@ -1084,9 +1083,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
@Override
|
||||
public void showTitle(@NotNull Title 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()));
|
||||
Collection<TitlePacket> packet = TitlePacket.of(Title.title(title.title(), title.subtitle(), title.times()));
|
||||
|
||||
for (TitlePacket titlePacket : packet) {
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
@ -1095,7 +1092,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
@Override
|
||||
public void sendActionBar(@NotNull Component message) {
|
||||
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, MinecraftServer.getSerializationManager().prepare(message, this));
|
||||
TitlePacket titlePacket = new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, message);
|
||||
playerConnection.sendPacket(titlePacket);
|
||||
}
|
||||
|
||||
@ -1924,9 +1921,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().prepare(component, this));
|
||||
disconnectPacket = new LoginDisconnectPacket(component);
|
||||
} else {
|
||||
disconnectPacket = new DisconnectPacket(MinecraftServer.getSerializationManager().prepare(component, this));
|
||||
disconnectPacket = new DisconnectPacket(component);
|
||||
}
|
||||
|
||||
if (playerConnection instanceof NettyPlayerConnection) {
|
||||
|
@ -209,8 +209,8 @@ public class WrittenBookMeta extends ItemMeta {
|
||||
WrittenBookMeta meta = new WrittenBookMeta();
|
||||
meta.resolved = false;
|
||||
meta.generation = WrittenBookGeneration.ORIGINAL;
|
||||
meta.author = MinecraftServer.getSerializationManager().prepareAndSerialize(book.author(), localizable);
|
||||
meta.title = MinecraftServer.getSerializationManager().prepareAndSerialize(book.title(), localizable);
|
||||
meta.author = MinecraftServer.getSerializationManager().translateAndSerialize(book.author(), localizable);
|
||||
meta.title = MinecraftServer.getSerializationManager().translateAndSerialize(book.title(), localizable);
|
||||
meta.pages = new ArrayList<>();
|
||||
|
||||
for (Component page : book.pages()) {
|
||||
|
@ -3,12 +3,9 @@ package net.minestom.server.network;
|
||||
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;
|
||||
@ -155,8 +152,9 @@ public final class ConnectionManager implements ForwardingAudience {
|
||||
final Collection<Player> recipients = getRecipients(condition);
|
||||
|
||||
if (!recipients.isEmpty()) {
|
||||
final String jsonText = jsonMessage.toString();
|
||||
LocalizablePacketSender.sendGroupedMessage(recipients, Identity.nil(), jsonMessage.asComponent(), MessageType.CHAT);
|
||||
for (Player recipient : recipients) {
|
||||
recipient.sendMessage(jsonMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -489,7 +487,6 @@ public final class ConnectionManager implements ForwardingAudience {
|
||||
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);
|
||||
|
@ -0,0 +1,8 @@
|
||||
package net.minestom.server.network.packet.server;
|
||||
|
||||
import net.minestom.server.adventure.ComponentHolder;
|
||||
|
||||
/**
|
||||
* A server packet that can hold components.
|
||||
*/
|
||||
public interface ComponentHoldingServerPacket extends ServerPacket, ComponentHolder<ServerPacket> { }
|
@ -2,14 +2,17 @@ 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.ComponentHoldingServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LoginDisconnectPacket implements ServerPacket {
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
private final Component kickMessage; // JSON text
|
||||
public class LoginDisconnectPacket implements ComponentHoldingServerPacket {
|
||||
public Component kickMessage;
|
||||
|
||||
public LoginDisconnectPacket(@NotNull Component kickMessage) {
|
||||
this.kickMessage = kickMessage;
|
||||
@ -33,4 +36,13 @@ public class LoginDisconnectPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.LOGIN_DISCONNECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
return List.of(this.kickMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull LoginDisconnectPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
return new LoginDisconnectPacket(operator.apply(this.kickMessage));
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,20 @@ package net.minestom.server.network.packet.server.play;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.advancements.FrameType;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AdvancementsPacket implements ServerPacket {
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class AdvancementsPacket implements ComponentHoldingServerPacket {
|
||||
|
||||
public boolean resetAdvancements;
|
||||
public AdvancementMapping[] advancementMappings;
|
||||
@ -37,6 +44,32 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.ADVANCEMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
List<Component> components = new ArrayList<>();
|
||||
for (AdvancementMapping advancementMapping : advancementMappings) {
|
||||
components.add(advancementMapping.value.displayData.title);
|
||||
components.add(advancementMapping.value.displayData.description);
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
AdvancementsPacket packet = new AdvancementsPacket();
|
||||
packet.resetAdvancements = this.resetAdvancements;
|
||||
packet.advancementMappings = Arrays.copyOf(this.advancementMappings, this.advancementMappings.length);
|
||||
packet.identifiersToRemove = Arrays.copyOf(this.identifiersToRemove, this.identifiersToRemove.length);
|
||||
packet.progressMappings = Arrays.copyOf(this.progressMappings, this.progressMappings.length);
|
||||
|
||||
for (AdvancementMapping advancementMapping : packet.advancementMappings) {
|
||||
advancementMapping.value.displayData.title = operator.apply(advancementMapping.value.displayData.title);
|
||||
advancementMapping.value.displayData.description = operator.apply(advancementMapping.value.displayData.title);
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* AdvancementMapping maps the namespaced ID to the Advancement.
|
||||
*/
|
||||
|
@ -3,14 +3,18 @@ package net.minestom.server.network.packet.server.play;
|
||||
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.ComponentHoldingServerPacket;
|
||||
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 java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class BossBarPacket implements ServerPacket {
|
||||
public class BossBarPacket implements ComponentHoldingServerPacket {
|
||||
|
||||
public UUID uuid;
|
||||
public Action action;
|
||||
@ -58,6 +62,40 @@ public class BossBarPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.BOSS_BAR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (title != null) {
|
||||
return Collections.singleton(title);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
switch (action) {
|
||||
case UPDATE_TITLE: {
|
||||
BossBarPacket packet = new BossBarPacket();
|
||||
packet.action = action;
|
||||
packet.uuid = uuid;
|
||||
packet.title = operator.apply(title);
|
||||
return packet;
|
||||
}
|
||||
case ADD: {
|
||||
BossBarPacket packet = new BossBarPacket();
|
||||
packet.action = action;
|
||||
packet.uuid = uuid;
|
||||
packet.title = operator.apply(title);
|
||||
packet.health = health;
|
||||
packet.overlay = overlay;
|
||||
packet.color = color;
|
||||
packet.flags = flags;
|
||||
return packet;
|
||||
}
|
||||
default: return this;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
ADD,
|
||||
REMOVE,
|
||||
|
@ -2,18 +2,22 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Represents an outgoing chat message packet.
|
||||
*/
|
||||
public class ChatMessagePacket implements ServerPacket {
|
||||
public class ChatMessagePacket implements ComponentHoldingServerPacket {
|
||||
private static final UUID NULL_UUID = new UUID(0, 0);
|
||||
|
||||
public Component message;
|
||||
@ -42,6 +46,16 @@ public class ChatMessagePacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.CHAT_MESSAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
return Collections.singleton(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
return new ChatMessagePacket(operator.apply(message), position, uuid);
|
||||
}
|
||||
|
||||
public enum Position {
|
||||
CHAT(MessageType.CHAT),
|
||||
SYSTEM_MESSAGE(MessageType.SYSTEM),
|
||||
|
@ -4,16 +4,21 @@ import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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 java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
public class CombatEventPacket implements ServerPacket {
|
||||
public class CombatEventPacket implements ComponentHoldingServerPacket {
|
||||
|
||||
private EventType type;
|
||||
private int duration;
|
||||
@ -81,6 +86,29 @@ public class CombatEventPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.COMBAT_EVENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (this.type == EventType.DEATH) {
|
||||
return Collections.singleton(deathMessage);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (this.type == EventType.DEATH) {
|
||||
CombatEventPacket packet = new CombatEventPacket();
|
||||
packet.type = type;
|
||||
packet.playerID = playerID;
|
||||
packet.opponent = opponent;
|
||||
packet.deathMessage = deathMessage;
|
||||
return packet;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public enum EventType {
|
||||
ENTER_COMBAT, END_COMBAT, // both ignored by Notchian client
|
||||
DEATH,
|
||||
|
@ -2,12 +2,17 @@ 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.ComponentHoldingServerPacket;
|
||||
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;
|
||||
|
||||
public class DisconnectPacket implements ServerPacket {
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class DisconnectPacket implements ComponentHoldingServerPacket {
|
||||
public Component message;
|
||||
|
||||
/**
|
||||
@ -35,4 +40,14 @@ public class DisconnectPacket implements ServerPacket {
|
||||
public int getId() {
|
||||
return ServerPacketIdentifier.DISCONNECT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
return Collections.singleton(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
return new DisconnectPacket(operator.apply(message));
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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;
|
||||
|
||||
public class MapDataPacket implements ServerPacket {
|
||||
import java.util.*;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class MapDataPacket implements ComponentHoldingServerPacket {
|
||||
|
||||
public int mapId;
|
||||
public byte scale;
|
||||
@ -59,6 +63,44 @@ public class MapDataPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.MAP_DATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (icons == null || icons.length == 0) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
List<Component> components = new ArrayList<>();
|
||||
for (Icon icon : icons) {
|
||||
components.add(icon.displayName);
|
||||
}
|
||||
return components;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (this.icons == null || this.icons.length == 0) {
|
||||
return this;
|
||||
} else {
|
||||
MapDataPacket packet = new MapDataPacket();
|
||||
packet.mapId = this.mapId;
|
||||
packet.scale = this.scale;
|
||||
packet.trackingPosition = this.trackingPosition;
|
||||
packet.locked = this.locked;
|
||||
packet.columns = this.columns;
|
||||
packet.rows = this.rows;
|
||||
packet.x = this.x;
|
||||
packet.z = this.z;
|
||||
packet.data = this.data;
|
||||
|
||||
packet.icons = Arrays.copyOf(this.icons, this.icons.length);
|
||||
for (Icon icon : packet.icons) {
|
||||
icon.displayName = operator.apply(icon.displayName);
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Icon {
|
||||
public int type;
|
||||
public byte x, z;
|
||||
|
@ -1,18 +1,19 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.adventure.ComponentHolder;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class PlayerInfoPacket implements ServerPacket {
|
||||
public class PlayerInfoPacket implements ComponentHoldingServerPacket {
|
||||
|
||||
public Action action;
|
||||
public List<PlayerInfo> playerInfos;
|
||||
@ -39,6 +40,40 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.PLAYER_INFO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
switch (this.action) {
|
||||
case ADD_PLAYER:
|
||||
case UPDATE_DISPLAY_NAME:
|
||||
List<Component> components = new ArrayList<>();
|
||||
for (PlayerInfo playerInfo : playerInfos) {
|
||||
if (playerInfo instanceof ComponentHolder) {
|
||||
components.addAll(((ComponentHolder<? extends PlayerInfo>) playerInfo).components());
|
||||
}
|
||||
}
|
||||
return components;
|
||||
default: return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
switch (this.action) {
|
||||
case ADD_PLAYER:
|
||||
case UPDATE_DISPLAY_NAME:
|
||||
PlayerInfoPacket packet = new PlayerInfoPacket(action);
|
||||
packet.playerInfos = new ArrayList<>(playerInfos.size());
|
||||
for (PlayerInfo playerInfo : playerInfos) {
|
||||
if (playerInfo instanceof ComponentHolder) {
|
||||
playerInfos.add(((ComponentHolder<? extends PlayerInfo>) playerInfo).copyWithOperator(operator));
|
||||
} else {
|
||||
playerInfos.add(playerInfo);
|
||||
}
|
||||
}
|
||||
default: return this;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
|
||||
ADD_PLAYER(AddPlayer.class),
|
||||
@ -70,7 +105,7 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
public abstract void write(BinaryWriter writer);
|
||||
}
|
||||
|
||||
public static class AddPlayer extends PlayerInfo {
|
||||
public static class AddPlayer extends PlayerInfo implements ComponentHolder<AddPlayer> {
|
||||
|
||||
public String name;
|
||||
public List<Property> properties;
|
||||
@ -102,6 +137,26 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
writer.writeComponent(displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (displayName == null) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Collections.singleton(displayName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull AddPlayer copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (displayName == null) {
|
||||
return this;
|
||||
} else {
|
||||
AddPlayer addPlayer = new AddPlayer(uuid, name, gameMode, ping);
|
||||
addPlayer.displayName = operator.apply(displayName);
|
||||
return addPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Property {
|
||||
|
||||
public String name;
|
||||
@ -160,7 +215,7 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
}
|
||||
}
|
||||
|
||||
public static class UpdateDisplayName extends PlayerInfo {
|
||||
public static class UpdateDisplayName extends PlayerInfo implements ComponentHolder<UpdateDisplayName> {
|
||||
|
||||
public Component displayName;
|
||||
|
||||
@ -184,6 +239,24 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
if (hasDisplayName)
|
||||
writer.writeComponent(displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (displayName == null) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Collections.singleton(displayName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull UpdateDisplayName copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (displayName == null) {
|
||||
return this;
|
||||
} else {
|
||||
return new UpdateDisplayName(uuid, operator.apply(displayName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RemovePlayer extends PlayerInfo {
|
||||
|
@ -1,15 +1,20 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class PlayerListHeaderAndFooterPacket implements ServerPacket {
|
||||
public class PlayerListHeaderAndFooterPacket implements ComponentHoldingServerPacket {
|
||||
public Component header;
|
||||
public Component footer;
|
||||
|
||||
@ -28,4 +33,21 @@ public class PlayerListHeaderAndFooterPacket implements ServerPacket {
|
||||
public int getId() {
|
||||
return ServerPacketIdentifier.PLAYER_LIST_HEADER_AND_FOOTER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
List<Component> components = new ArrayList<>();
|
||||
if (header != null) {
|
||||
components.add(header);
|
||||
}
|
||||
if (footer != null) {
|
||||
components.add(footer);
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
return new PlayerListHeaderAndFooterPacket(header == null ? null : operator.apply(header), footer == null ? null : operator.apply(footer));
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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;
|
||||
|
||||
public class ScoreboardObjectivePacket implements ServerPacket {
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class ScoreboardObjectivePacket implements ComponentHoldingServerPacket {
|
||||
|
||||
/**
|
||||
* An unique name for the objective
|
||||
@ -43,6 +48,29 @@ public class ScoreboardObjectivePacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.SCOREBOARD_OBJECTIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (mode == 0 || mode == 2) {
|
||||
return Collections.singleton(objectiveValue);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (mode == 0 || mode == 2) {
|
||||
ScoreboardObjectivePacket packet = new ScoreboardObjectivePacket();
|
||||
packet.objectiveName = objectiveName;
|
||||
packet.mode = mode;
|
||||
packet.objectiveValue = operator.apply(objectiveValue);
|
||||
packet.type = type;
|
||||
return packet;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This enumeration represents all available types for the scoreboard objective
|
||||
*/
|
||||
|
@ -1,12 +1,20 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.adventure.ComponentHolder;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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;
|
||||
|
||||
public class TabCompletePacket implements ServerPacket {
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class TabCompletePacket implements ComponentHoldingServerPacket {
|
||||
|
||||
public int transactionId;
|
||||
public int start;
|
||||
@ -33,10 +41,66 @@ public class TabCompletePacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.TAB_COMPLETE;
|
||||
}
|
||||
|
||||
public static class Match {
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (matches == null || matches.length == 0) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
List<Component> components = new ArrayList<>(matches.length);
|
||||
for (Match match : matches) {
|
||||
if (match.hasTooltip) {
|
||||
components.add(match.tooltip);
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (matches == null || matches.length == 0) {
|
||||
return this;
|
||||
} else {
|
||||
TabCompletePacket packet = new TabCompletePacket();
|
||||
packet.transactionId = transactionId;
|
||||
packet.start = start;
|
||||
packet.length = length;
|
||||
packet.matches = new Match[matches.length];
|
||||
|
||||
for (int i = 0; i < matches.length; i++) {
|
||||
packet.matches[i] = matches[i].copyWithOperator(operator);
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Match implements ComponentHolder<Match> {
|
||||
public String match;
|
||||
public boolean hasTooltip;
|
||||
public Component tooltip;
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (hasTooltip) {
|
||||
return Collections.singleton(tooltip);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Match copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (hasTooltip) {
|
||||
Match newMatch = new Match();
|
||||
newMatch.match = match;
|
||||
newMatch.hasTooltip = hasTooltip;
|
||||
newMatch.tooltip = tooltip;
|
||||
return newMatch;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,15 +2,21 @@ package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.color.TeamColor;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
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 java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* The packet creates or updates teams
|
||||
*/
|
||||
public class TeamsPacket implements ServerPacket {
|
||||
public class TeamsPacket implements ComponentHoldingServerPacket {
|
||||
|
||||
/**
|
||||
* The registry name of the team
|
||||
@ -100,6 +106,35 @@ public class TeamsPacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.TEAMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (this.action == Action.UPDATE_TEAM_INFO || this.action == Action.CREATE_TEAM) {
|
||||
return List.of(teamDisplayName, teamPrefix, teamSuffix);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (this.action == Action.UPDATE_TEAM_INFO || this.action == Action.CREATE_TEAM) {
|
||||
TeamsPacket packet = new TeamsPacket();
|
||||
packet.teamName = teamName;
|
||||
packet.action = action;
|
||||
packet.teamDisplayName = teamDisplayName == null ? null : operator.apply(teamDisplayName);
|
||||
packet.friendlyFlags = friendlyFlags;
|
||||
packet.nameTagVisibility = nameTagVisibility;
|
||||
packet.collisionRule = collisionRule;
|
||||
packet.teamColor = teamColor;
|
||||
packet.teamPrefix = teamPrefix == null ? null : operator.apply(teamPrefix);
|
||||
packet.teamSuffix = teamSuffix == null ? null : operator.apply(teamSuffix);
|
||||
packet.entities = entities;
|
||||
return packet;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An enumeration which representing all actions for the packet
|
||||
*/
|
||||
|
@ -2,6 +2,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.network.packet.server.ComponentHoldingServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.TickUtils;
|
||||
@ -11,11 +12,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import static net.minestom.server.network.packet.server.play.TitlePacket.Action.*;
|
||||
|
||||
public class TitlePacket implements ServerPacket {
|
||||
public class TitlePacket implements ComponentHoldingServerPacket {
|
||||
|
||||
public Action action;
|
||||
|
||||
@ -90,6 +93,24 @@ public class TitlePacket implements ServerPacket {
|
||||
return ServerPacketIdentifier.TITLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Collection<Component> components() {
|
||||
if (action == SET_TITLE || action == SET_SUBTITLE || action == SET_ACTION_BAR) {
|
||||
return Collections.singleton(payload);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
|
||||
if (action == SET_TITLE || action == SET_SUBTITLE || action == SET_ACTION_BAR) {
|
||||
return new TitlePacket(action, operator.apply(payload));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
SET_TITLE,
|
||||
SET_SUBTITLE,
|
||||
|
@ -13,6 +13,7 @@ import net.minestom.server.network.ConnectionState;
|
||||
import net.minestom.server.network.netty.NettyServer;
|
||||
import net.minestom.server.network.netty.codec.PacketCompressor;
|
||||
import net.minestom.server.network.netty.packet.FramedPacket;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.login.SetCompressionPacket;
|
||||
import net.minestom.server.utils.BufUtils;
|
||||
@ -25,6 +26,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.awt.Component;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -180,6 +182,11 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
return;
|
||||
} else if (message instanceof ServerPacket) {
|
||||
final ServerPacket serverPacket = (ServerPacket) message;
|
||||
|
||||
if (getPlayer() != null && serverPacket instanceof ComponentHoldingServerPacket) {
|
||||
serverPacket = ((ComponentHoldingServerPacket) serverPacket).copyWithOperator(component -> MinecraftServer.getSerializationManager().translate(component, getPlayer()));
|
||||
}
|
||||
|
||||
synchronized (tickBuffer) {
|
||||
PacketUtils.writeFramedPacket(tickBuffer, serverPacket, false);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.listener.manager.PacketListenerManager;
|
||||
import net.minestom.server.network.netty.packet.FramedPacket;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.player.NettyPlayerConnection;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
@ -45,7 +46,14 @@ public final class PacketUtils {
|
||||
if (players.isEmpty())
|
||||
return;
|
||||
|
||||
if (MinecraftServer.hasGroupedPacket()) {
|
||||
// work out if the packet needs to be sent individually due to server-side translating
|
||||
boolean needsTranslating = false;
|
||||
|
||||
if (packet instanceof ComponentHoldingServerPacket) {
|
||||
needsTranslating = MinecraftServer.getSerializationManager().areAnyTranslatable(((ComponentHoldingServerPacket) packet).components());
|
||||
}
|
||||
|
||||
if (MinecraftServer.hasGroupedPacket() && !needsTranslating) {
|
||||
// Send grouped packet...
|
||||
final boolean success = PACKET_LISTENER_MANAGER.processServerPacket(packet, players);
|
||||
if (success) {
|
||||
|
Loading…
Reference in New Issue
Block a user