Add ComponentHolderServerPacket to some packets (#1275)

This commit is contained in:
Marfien 2022-09-02 22:23:42 +02:00 committed by GitHub
parent c270712798
commit eef95ae5d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 525 additions and 38 deletions

View File

@ -1,13 +1,18 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public record ActionBarPacket(@NotNull Component text) implements ServerPacket { import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
public record ActionBarPacket(@NotNull Component text) implements ComponentHoldingServerPacket {
public ActionBarPacket(BinaryReader reader) { public ActionBarPacket(BinaryReader reader) {
this(reader.readComponent()); this(reader.readComponent());
} }
@ -21,4 +26,14 @@ public record ActionBarPacket(@NotNull Component text) implements ServerPacket {
public int getId() { public int getId() {
return ServerPacketIdentifier.ACTION_BAR; return ServerPacketIdentifier.ACTION_BAR;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.text);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new ActionBarPacket(operator.apply(this.text));
}
} }

View File

@ -2,7 +2,9 @@ package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.minestom.server.advancements.FrameType; import net.minestom.server.advancements.FrameType;
import net.minestom.server.adventure.ComponentHolder;
import net.minestom.server.item.ItemStack; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
@ -11,11 +13,13 @@ import net.minestom.server.utils.binary.Writeable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.*;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping> advancementMappings, public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping> advancementMappings,
@NotNull List<String> identifiersToRemove, @NotNull List<String> identifiersToRemove,
@NotNull List<ProgressMapping> progressMappings) implements ServerPacket { @NotNull List<ProgressMapping> progressMappings) implements ComponentHoldingServerPacket {
public AdvancementsPacket { public AdvancementsPacket {
advancementMappings = List.copyOf(advancementMappings); advancementMappings = List.copyOf(advancementMappings);
identifiersToRemove = List.copyOf(identifiersToRemove); identifiersToRemove = List.copyOf(identifiersToRemove);
@ -41,10 +45,35 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
return ServerPacketIdentifier.ADVANCEMENTS; return ServerPacketIdentifier.ADVANCEMENTS;
} }
// TODO is the display-item needed to be updated?
@Override
public @NotNull Collection<Component> components() {
final var displayData = this.advancementMappings.stream().map(AdvancementMapping::value).map(Advancement::displayData).filter(Objects::nonNull).toList();
final var titles = displayData.stream().map(DisplayData::title).toList();
final var descriptions = displayData.stream().map(DisplayData::description).toList();
final var list = new ArrayList<Component>();
list.addAll(titles);
list.addAll(descriptions);
return List.copyOf(list);
}
@Override
public @NotNull ServerPacket copyWithOperator(final @NotNull UnaryOperator<Component> operator) {
return new AdvancementsPacket(
this.reset,
this.advancementMappings.stream().map(mapping -> mapping.copyWithOperator(operator)).toList(),
this.identifiersToRemove,
this.progressMappings
);
}
/** /**
* AdvancementMapping maps the namespaced ID to the Advancement. * AdvancementMapping maps the namespaced ID to the Advancement.
*/ */
public record AdvancementMapping(@NotNull String key, @NotNull Advancement value) implements Writeable { public record AdvancementMapping(@NotNull String key, @NotNull Advancement value) implements Writeable, ComponentHolder<AdvancementMapping> {
public AdvancementMapping(BinaryReader reader) { public AdvancementMapping(BinaryReader reader) {
this(reader.readSizedString(), new Advancement(reader)); this(reader.readSizedString(), new Advancement(reader));
} }
@ -54,11 +83,21 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
writer.writeSizedString(key); writer.writeSizedString(key);
writer.write(value); writer.write(value);
} }
@Override
public @NotNull Collection<Component> components() {
return this.value.components();
}
@Override
public @NotNull AdvancementMapping copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return this.value.displayData == null ? this : new AdvancementMapping(this.key, this.value.copyWithOperator(operator));
}
} }
public record Advancement(@Nullable String parentIdentifier, @Nullable DisplayData displayData, public record Advancement(@Nullable String parentIdentifier, @Nullable DisplayData displayData,
@NotNull List<String> criteria, @NotNull List<String> criteria,
@NotNull List<Requirement> requirements) implements Writeable { @NotNull List<Requirement> requirements) implements Writeable, ComponentHolder<Advancement> {
public Advancement { public Advancement {
criteria = List.copyOf(criteria); criteria = List.copyOf(criteria);
requirements = List.copyOf(requirements); requirements = List.copyOf(requirements);
@ -80,6 +119,16 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
writer.writeVarIntList(criteria, BinaryWriter::writeSizedString); writer.writeVarIntList(criteria, BinaryWriter::writeSizedString);
writer.writeVarIntList(requirements, BinaryWriter::write); writer.writeVarIntList(requirements, BinaryWriter::write);
} }
@Override
public @NotNull Collection<Component> components() {
return this.displayData != null ? this.displayData.components() : List.of();
}
@Override
public @NotNull Advancement copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return this.displayData == null ? this : new Advancement(this.parentIdentifier, this.displayData.copyWithOperator(operator), this.criteria, this.requirements);
}
} }
public record Requirement(@NotNull List<String> requirements) implements Writeable { public record Requirement(@NotNull List<String> requirements) implements Writeable {
@ -100,7 +149,7 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
public record DisplayData(@NotNull Component title, @NotNull Component description, public record DisplayData(@NotNull Component title, @NotNull Component description,
@NotNull ItemStack icon, @NotNull FrameType frameType, @NotNull ItemStack icon, @NotNull FrameType frameType,
int flags, @Nullable String backgroundTexture, int flags, @Nullable String backgroundTexture,
float x, float y) implements Writeable { float x, float y) implements Writeable, ComponentHolder<DisplayData> {
public DisplayData(BinaryReader reader) { public DisplayData(BinaryReader reader) {
this(read(reader)); this(read(reader));
} }
@ -141,6 +190,16 @@ public record AdvancementsPacket(boolean reset, @NotNull List<AdvancementMapping
writer.writeFloat(x); writer.writeFloat(x);
writer.writeFloat(y); writer.writeFloat(y);
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.title, this.description);
}
@Override
public @NotNull DisplayData copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new DisplayData(operator.apply(this.title), operator.apply(this.description), this.icon, this.frameType, this.flags, this.backgroundTexture, this.x, this.y);
}
} }
public record ProgressMapping(@NotNull String key, @NotNull AdvancementProgress progress) implements Writeable { public record ProgressMapping(@NotNull String key, @NotNull AdvancementProgress progress) implements Writeable {

View File

@ -3,6 +3,8 @@ package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.minestom.server.adventure.AdventurePacketConvertor; import net.minestom.server.adventure.AdventurePacketConvertor;
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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
@ -10,9 +12,12 @@ import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.binary.Writeable; import net.minestom.server.utils.binary.Writeable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.UnaryOperator;
public record BossBarPacket(@NotNull UUID uuid, @NotNull Action action) implements ServerPacket { public record BossBarPacket(@NotNull UUID uuid, @NotNull Action action) implements ComponentHoldingServerPacket {
public BossBarPacket(BinaryReader reader) { public BossBarPacket(BinaryReader reader) {
this(reader.readUuid(), switch (reader.readVarInt()) { this(reader.readUuid(), switch (reader.readVarInt()) {
case 0 -> new AddAction(reader); case 0 -> new AddAction(reader);
@ -32,13 +37,27 @@ public record BossBarPacket(@NotNull UUID uuid, @NotNull Action action) implemen
writer.write(action); writer.write(action);
} }
@Override
public @NotNull Collection<Component> components() {
return this.action instanceof ComponentHolder<?> holder
? holder.components()
: List.of();
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return this.action instanceof ComponentHolder<?> holder
? new BossBarPacket(this.uuid, (Action) holder.copyWithOperator(operator))
: this;
}
public sealed interface Action extends Writeable public sealed interface Action extends Writeable
permits AddAction, RemoveAction, UpdateHealthAction, UpdateTitleAction, UpdateStyleAction, UpdateFlagsAction { permits AddAction, RemoveAction, UpdateHealthAction, UpdateTitleAction, UpdateStyleAction, UpdateFlagsAction {
int id(); int id();
} }
public record AddAction(@NotNull Component title, float health, @NotNull BossBar.Color color, public record AddAction(@NotNull Component title, float health, @NotNull BossBar.Color color,
@NotNull BossBar.Overlay overlay, byte flags) implements Action { @NotNull BossBar.Overlay overlay, byte flags) implements Action, ComponentHolder<AddAction> {
public AddAction(@NotNull BossBar bar) { public AddAction(@NotNull BossBar bar) {
this(bar.name(), bar.progress(), bar.color(), bar.overlay(), this(bar.name(), bar.progress(), bar.color(), bar.overlay(),
AdventurePacketConvertor.getBossBarFlagValue(bar.flags())); AdventurePacketConvertor.getBossBarFlagValue(bar.flags()));
@ -63,6 +82,16 @@ public record BossBarPacket(@NotNull UUID uuid, @NotNull Action action) implemen
public int id() { public int id() {
return 0; return 0;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.title);
}
@Override
public @NotNull AddAction copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new AddAction(operator.apply(this.title), this.health, this.color, this.overlay, this.flags);
}
} }
public record RemoveAction() implements Action { public record RemoveAction() implements Action {
@ -96,7 +125,7 @@ public record BossBarPacket(@NotNull UUID uuid, @NotNull Action action) implemen
} }
} }
public record UpdateTitleAction(@NotNull Component title) implements Action { public record UpdateTitleAction(@NotNull Component title) implements Action, ComponentHolder<UpdateTitleAction> {
public UpdateTitleAction(@NotNull BossBar bar) { public UpdateTitleAction(@NotNull BossBar bar) {
this(bar.name()); this(bar.name());
} }
@ -114,6 +143,16 @@ public record BossBarPacket(@NotNull UUID uuid, @NotNull Action action) implemen
public int id() { public int id() {
return 3; return 3;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.title);
}
@Override
public @NotNull UpdateTitleAction copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new UpdateTitleAction(operator.apply(this.title));
}
} }
public record UpdateStyleAction(@NotNull BossBar.Color color, public record UpdateStyleAction(@NotNull BossBar.Color color,

View File

@ -10,7 +10,7 @@ import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
@ -38,7 +38,7 @@ public record ChatMessagePacket(@NotNull Component message, @NotNull ChatPositio
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
return Collections.singleton(message); return List.of(message);
} }
@Override @Override

View File

@ -1,14 +1,19 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
public record DeathCombatEventPacket(int playerId, int entityId, public record DeathCombatEventPacket(int playerId, int entityId,
@NotNull Component message) implements ServerPacket { @NotNull Component message) implements ComponentHoldingServerPacket {
public DeathCombatEventPacket(BinaryReader reader) { public DeathCombatEventPacket(BinaryReader reader) {
this(reader.readVarInt(), reader.readInt(), reader.readComponent()); this(reader.readVarInt(), reader.readInt(), reader.readComponent());
} }
@ -24,4 +29,14 @@ public record DeathCombatEventPacket(int playerId, int entityId,
public int getId() { public int getId() {
return ServerPacketIdentifier.DEATH_COMBAT_EVENT; return ServerPacketIdentifier.DEATH_COMBAT_EVENT;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.message);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new DeathCombatEventPacket(this.playerId, this.entityId, operator.apply(this.message));
}
} }

View File

@ -9,7 +9,7 @@ import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.List;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
public record DisconnectPacket(@NotNull Component message) implements ComponentHoldingServerPacket { public record DisconnectPacket(@NotNull Component message) implements ComponentHoldingServerPacket {
@ -29,7 +29,7 @@ public record DisconnectPacket(@NotNull Component message) implements ComponentH
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
return Collections.singleton(message); return List.of(message);
} }
@Override @Override

View File

@ -1,18 +1,24 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.entity.EquipmentSlot;
import net.minestom.server.item.ItemStack; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public record EntityEquipmentPacket(int entityId, public record EntityEquipmentPacket(int entityId,
@NotNull Map<EquipmentSlot, ItemStack> equipments) implements ServerPacket { @NotNull Map<EquipmentSlot, ItemStack> equipments) implements ComponentHoldingServerPacket {
public EntityEquipmentPacket { public EntityEquipmentPacket {
equipments = Map.copyOf(equipments); equipments = Map.copyOf(equipments);
if (equipments.isEmpty()) if (equipments.isEmpty())
@ -41,6 +47,23 @@ public record EntityEquipmentPacket(int entityId,
return ServerPacketIdentifier.ENTITY_EQUIPMENT; return ServerPacketIdentifier.ENTITY_EQUIPMENT;
} }
@Override
public @NotNull Collection<Component> components() {
return this.equipments.values()
.stream()
.map(ItemStack::getDisplayName)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
final var map = new EnumMap<EquipmentSlot, ItemStack>(EquipmentSlot.class);
this.equipments.forEach((key, value) -> map.put(key, value.withDisplayName(operator)));
return new EntityEquipmentPacket(this.entityId, map);
}
private static Map<EquipmentSlot, ItemStack> readEquipments(BinaryReader reader) { private static Map<EquipmentSlot, ItemStack> readEquipments(BinaryReader reader) {
Map<EquipmentSlot, ItemStack> equipments = new EnumMap<>(EquipmentSlot.class); Map<EquipmentSlot, ItemStack> equipments = new EnumMap<>(EquipmentSlot.class);
byte slot; byte slot;

View File

@ -1,17 +1,21 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.Metadata; import net.minestom.server.entity.Metadata;
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.UnaryOperator;
public record EntityMetaDataPacket(int entityId, public record EntityMetaDataPacket(int entityId,
@NotNull Map<Integer, Metadata.Entry<?>> entries) implements ServerPacket { @NotNull Map<Integer, Metadata.Entry<?>> entries) implements ComponentHoldingServerPacket {
public EntityMetaDataPacket { public EntityMetaDataPacket {
entries = Map.copyOf(entries); entries = Map.copyOf(entries);
} }
@ -47,4 +51,27 @@ public record EntityMetaDataPacket(int entityId,
public int getId() { public int getId() {
return ServerPacketIdentifier.ENTITY_METADATA; return ServerPacketIdentifier.ENTITY_METADATA;
} }
@Override
public @NotNull Collection<Component> components() {
return this.entries.values()
.stream()
.map(Metadata.Entry::value)
.filter(entry -> entry instanceof Component)
.map(entry -> (Component) entry)
.toList();
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
final var entries = new HashMap<Integer, Metadata.Entry<?>>();
this.entries.forEach((key, value) -> {
final var v = value.value();
entries.put(key, v instanceof Component c ? Metadata.OptChat(operator.apply(c)) : value);
});
return new EntityMetaDataPacket(this.entityId, entries);
}
} }

View File

@ -1,14 +1,19 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
public record OpenWindowPacket(int windowId, int windowType, public record OpenWindowPacket(int windowId, int windowType,
@NotNull Component title) implements ServerPacket { @NotNull Component title) implements ComponentHoldingServerPacket {
public OpenWindowPacket(BinaryReader reader) { public OpenWindowPacket(BinaryReader reader) {
this(reader.readVarInt(), reader.readVarInt(), reader.readComponent()); this(reader.readVarInt(), reader.readVarInt(), reader.readComponent());
} }
@ -24,4 +29,14 @@ public record OpenWindowPacket(int windowId, int windowType,
public int getId() { public int getId() {
return ServerPacketIdentifier.OPEN_WINDOW; return ServerPacketIdentifier.OPEN_WINDOW;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.title);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new OpenWindowPacket(this.windowId, this.windowType, operator.apply(this.title));
}
} }

View File

@ -81,7 +81,7 @@ public record PlayerInfoPacket(@NotNull Action action,
} }
return components; return components;
default: default:
return Collections.emptyList(); return List.of();
} }
} }
@ -152,7 +152,7 @@ public record PlayerInfoPacket(@NotNull Action action,
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
return displayName != null ? Collections.singleton(displayName) : Collections.emptyList(); return displayName != null ? List.of(displayName) : List.of();
} }
@Override @Override
@ -218,7 +218,7 @@ public record PlayerInfoPacket(@NotNull Action action,
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
return displayName != null ? Collections.singleton(displayName) : Collections.emptyList(); return displayName != null ? List.of(displayName) : List.of();
} }
@Override @Override

View File

@ -1,6 +1,7 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.resourcepack.ResourcePack; import net.minestom.server.resourcepack.ResourcePack;
@ -8,8 +9,12 @@ import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
public record ResourcePackSendPacket(String url, String hash, boolean forced, public record ResourcePackSendPacket(String url, String hash, boolean forced,
Component prompt) implements ServerPacket { Component prompt) implements ComponentHoldingServerPacket {
public ResourcePackSendPacket(BinaryReader reader) { public ResourcePackSendPacket(BinaryReader reader) {
this(reader.readSizedString(), reader.readSizedString(), reader.readBoolean(), this(reader.readSizedString(), reader.readSizedString(), reader.readBoolean(),
reader.readBoolean() ? reader.readComponent() : null); reader.readBoolean() ? reader.readComponent() : null);
@ -37,4 +42,14 @@ public record ResourcePackSendPacket(String url, String hash, boolean forced,
public int getId() { public int getId() {
return ServerPacketIdentifier.RESOURCE_PACK_SEND; return ServerPacketIdentifier.RESOURCE_PACK_SEND;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.prompt);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new ResourcePackSendPacket(this.url, this.hash, this.forced, operator.apply(this.prompt));
}
} }

View File

@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
public record ScoreboardObjectivePacket(@NotNull String objectiveName, byte mode, public record ScoreboardObjectivePacket(@NotNull String objectiveName, byte mode,
@ -55,8 +56,8 @@ public record ScoreboardObjectivePacket(@NotNull String objectiveName, byte mode
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
return mode == 0 || mode == 2 ? Collections.singleton(objectiveValue) : return mode == 0 || mode == 2 ? List.of(objectiveValue) :
Collections.emptyList(); List.of();
} }
@Override @Override

View File

@ -1,14 +1,22 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemStack; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.UnaryOperator;
public record SetSlotPacket(byte windowId, int stateId, short slot, public record SetSlotPacket(byte windowId, int stateId, short slot,
@NotNull ItemStack itemStack) implements ServerPacket { @NotNull ItemStack itemStack) implements ComponentHoldingServerPacket {
public SetSlotPacket(BinaryReader reader) { public SetSlotPacket(BinaryReader reader) {
this(reader.readByte(), reader.readVarInt(), reader.readShort(), this(reader.readByte(), reader.readVarInt(), reader.readShort(),
reader.readItemStack()); reader.readItemStack());
@ -27,6 +35,24 @@ public record SetSlotPacket(byte windowId, int stateId, short slot,
return ServerPacketIdentifier.SET_SLOT; return ServerPacketIdentifier.SET_SLOT;
} }
@Override
public @NotNull Collection<Component> components() {
final var components = new ArrayList<>(this.itemStack.getLore());
final var displayname = this.itemStack.getDisplayName();
if (displayname != null) components.add(displayname);
return List.copyOf(components);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new SetSlotPacket(this.windowId, this.stateId, this.slot, this.itemStack.withDisplayName(operator).withLore(lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
}));
}
/** /**
* Returns a {@link SetSlotPacket} used to change a player cursor item. * Returns a {@link SetSlotPacket} used to change a player cursor item.
* *

View File

@ -1,13 +1,18 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public record SetTitleSubTitlePacket(@NotNull Component subtitle) implements ServerPacket { import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
public record SetTitleSubTitlePacket(@NotNull Component subtitle) implements ComponentHoldingServerPacket {
public SetTitleSubTitlePacket(BinaryReader reader) { public SetTitleSubTitlePacket(BinaryReader reader) {
this(reader.readComponent()); this(reader.readComponent());
} }
@ -21,4 +26,14 @@ public record SetTitleSubTitlePacket(@NotNull Component subtitle) implements Ser
public int getId() { public int getId() {
return ServerPacketIdentifier.SET_TITLE_SUBTITLE; return ServerPacketIdentifier.SET_TITLE_SUBTITLE;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.subtitle);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new SetTitleSubTitlePacket(operator.apply(this.subtitle));
}
} }

View File

@ -1,13 +1,18 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public record SetTitleTextPacket(@NotNull Component title) implements ServerPacket { import java.util.Collection;
import java.util.List;
import java.util.function.UnaryOperator;
public record SetTitleTextPacket(@NotNull Component title) implements ComponentHoldingServerPacket {
public SetTitleTextPacket(BinaryReader reader) { public SetTitleTextPacket(BinaryReader reader) {
this(reader.readComponent()); this(reader.readComponent());
} }
@ -21,4 +26,14 @@ public record SetTitleTextPacket(@NotNull Component title) implements ServerPack
public int getId() { public int getId() {
return ServerPacketIdentifier.SET_TITLE_TEXT; return ServerPacketIdentifier.SET_TITLE_TEXT;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.title);
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new SetTitleTextPacket(operator.apply(this.title));
}
} }

View File

@ -42,7 +42,7 @@ public record TabCompletePacket(int transactionId, int start, int length,
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
if (matches.isEmpty()) return Collections.emptyList(); if (matches.isEmpty()) return List.of();
List<Component> components = new ArrayList<>(matches.size()); List<Component> components = new ArrayList<>(matches.size());
for (Match match : matches) { for (Match match : matches) {
if (match.tooltip != null) { if (match.tooltip != null) {
@ -75,7 +75,7 @@ public record TabCompletePacket(int transactionId, int start, int length,
@Override @Override
public @NotNull Collection<Component> components() { public @NotNull Collection<Component> components() {
return tooltip != null ? Collections.singletonList(tooltip) : Collections.emptyList(); return tooltip != null ? Collections.singletonList(tooltip) : List.of();
} }
@Override @Override

View File

@ -3,6 +3,8 @@ package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.adventure.AdventurePacketConvertor; import net.minestom.server.adventure.AdventurePacketConvertor;
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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
@ -13,11 +15,12 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.UnaryOperator;
/** /**
* The packet creates or updates teams * The packet creates or updates teams
*/ */
public record TeamsPacket(String teamName, Action action) implements ServerPacket { public record TeamsPacket(String teamName, Action action) implements ComponentHoldingServerPacket {
public TeamsPacket(BinaryReader reader) { public TeamsPacket(BinaryReader reader) {
this(reader.readSizedString(), switch (reader.readByte()) { this(reader.readSizedString(), switch (reader.readByte()) {
case 0 -> new CreateTeamAction(reader); case 0 -> new CreateTeamAction(reader);
@ -36,6 +39,21 @@ public record TeamsPacket(String teamName, Action action) implements ServerPacke
writer.write(action); writer.write(action);
} }
@Override
public @NotNull Collection<Component> components() {
return this.action instanceof ComponentHolder<?> holder ? holder.components() : List.of();
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new TeamsPacket(
this.teamName,
this.action instanceof ComponentHolder<?> holder
? (Action) holder.copyWithOperator(operator)
: this.action
);
}
public sealed interface Action extends Writeable public sealed interface Action extends Writeable
permits CreateTeamAction, RemoveTeamAction, UpdateTeamAction, AddEntitiesToTeamAction, RemoveEntitiesToTeamAction { permits CreateTeamAction, RemoveTeamAction, UpdateTeamAction, AddEntitiesToTeamAction, RemoveEntitiesToTeamAction {
int id(); int id();
@ -44,7 +62,7 @@ public record TeamsPacket(String teamName, Action action) implements ServerPacke
public record CreateTeamAction(Component displayName, byte friendlyFlags, public record CreateTeamAction(Component displayName, byte friendlyFlags,
NameTagVisibility nameTagVisibility, CollisionRule collisionRule, NameTagVisibility nameTagVisibility, CollisionRule collisionRule,
NamedTextColor teamColor, Component teamPrefix, Component teamSuffix, NamedTextColor teamColor, Component teamPrefix, Component teamSuffix,
Collection<String> entities) implements Action { Collection<String> entities) implements Action, ComponentHolder<CreateTeamAction> {
public CreateTeamAction { public CreateTeamAction {
entities = List.copyOf(entities); entities = List.copyOf(entities);
} }
@ -72,6 +90,25 @@ public record TeamsPacket(String teamName, Action action) implements ServerPacke
public int id() { public int id() {
return 0; return 0;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.displayName, this.teamPrefix, this.teamSuffix);
}
@Override
public @NotNull CreateTeamAction copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new CreateTeamAction(
operator.apply(this.displayName),
this.friendlyFlags,
this.nameTagVisibility,
this.collisionRule,
this.teamColor,
operator.apply(this.teamPrefix),
operator.apply(this.teamSuffix),
entities
);
}
} }
public record RemoveTeamAction() implements Action { public record RemoveTeamAction() implements Action {
@ -88,7 +125,7 @@ public record TeamsPacket(String teamName, Action action) implements ServerPacke
public record UpdateTeamAction(Component displayName, byte friendlyFlags, public record UpdateTeamAction(Component displayName, byte friendlyFlags,
NameTagVisibility nameTagVisibility, CollisionRule collisionRule, NameTagVisibility nameTagVisibility, CollisionRule collisionRule,
NamedTextColor teamColor, NamedTextColor teamColor,
Component teamPrefix, Component teamSuffix) implements Action { Component teamPrefix, Component teamSuffix) implements Action, ComponentHolder<UpdateTeamAction> {
public UpdateTeamAction(BinaryReader reader) { public UpdateTeamAction(BinaryReader reader) {
this(reader.readComponent(), reader.readByte(), this(reader.readComponent(), reader.readByte(),
@ -112,6 +149,24 @@ public record TeamsPacket(String teamName, Action action) implements ServerPacke
public int id() { public int id() {
return 2; return 2;
} }
@Override
public @NotNull Collection<Component> components() {
return List.of(this.displayName, this.teamPrefix, this.teamSuffix);
}
@Override
public @NotNull UpdateTeamAction copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new UpdateTeamAction(
operator.apply(this.displayName),
this.friendlyFlags,
this.nameTagVisibility,
this.collisionRule,
this.teamColor,
operator.apply(this.teamPrefix),
operator.apply(this.teamSuffix)
);
}
} }
public record AddEntitiesToTeamAction(Collection<String> entities) implements Action { public record AddEntitiesToTeamAction(Collection<String> entities) implements Action {

View File

@ -1,16 +1,23 @@
package net.minestom.server.network.packet.server.play; package net.minestom.server.network.packet.server.play;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemStack; 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.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryReader;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemStack> items, public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemStack> items,
@NotNull ItemStack carriedItem) implements ServerPacket { @NotNull ItemStack carriedItem) implements ComponentHoldingServerPacket {
public WindowItemsPacket { public WindowItemsPacket {
items = List.copyOf(items); items = List.copyOf(items);
} }
@ -32,4 +39,41 @@ public record WindowItemsPacket(byte windowId, int stateId, @NotNull List<ItemSt
public int getId() { public int getId() {
return ServerPacketIdentifier.WINDOW_ITEMS; return ServerPacketIdentifier.WINDOW_ITEMS;
} }
@Override
public @NotNull Collection<Component> components() {
final var list = new ArrayList<>(this.items);
list.add(this.carriedItem);
final var components = new ArrayList<Component>();
list.forEach(itemStack -> {
components.addAll(itemStack.getLore());
final var displayName = itemStack.getDisplayName();
if (displayName == null) return;
components.add(displayName);
});
return components;
}
@Override
public @NotNull ServerPacket copyWithOperator(@NotNull UnaryOperator<Component> operator) {
return new WindowItemsPacket(
this.windowId,
this.stateId,
this.items.stream().map(stack -> stack.withDisplayName(operator).withLore(lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
})).toList(),
this.carriedItem.withDisplayName(operator).withLore(lines -> {
final var translatedComponents = new ArrayList<Component>();
lines.forEach(component -> translatedComponents.add(operator.apply(component)));
return translatedComponents;
})
);
}
} }

View File

@ -8,15 +8,16 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList; import it.unimi.dsi.fastutil.longs.LongList;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience; import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.Viewable; import net.minestom.server.Viewable;
import net.minestom.server.adventure.ComponentHolder;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.adventure.audience.PacketGroupingAudience; import net.minestom.server.adventure.audience.PacketGroupingAudience;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.network.packet.server.CachedPacket; import net.minestom.server.network.packet.server.*;
import net.minestom.server.network.packet.server.FramedPacket;
import net.minestom.server.network.packet.server.SendablePacket;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.network.player.PlayerSocketConnection; import net.minestom.server.network.player.PlayerSocketConnection;
import net.minestom.server.utils.binary.BinaryBuffer; import net.minestom.server.utils.binary.BinaryBuffer;
@ -101,12 +102,47 @@ public final class PacketUtils {
*/ */
public static void sendGroupedPacket(@NotNull Collection<Player> players, @NotNull ServerPacket packet, public static void sendGroupedPacket(@NotNull Collection<Player> players, @NotNull ServerPacket packet,
@NotNull Predicate<Player> predicate) { @NotNull Predicate<Player> predicate) {
final SendablePacket sendablePacket = GROUPED_PACKET ? new CachedPacket(packet) : packet; final var sendablePacket = shouldUseCachePacket(packet) ? new CachedPacket(packet) : packet;
players.forEach(player -> { players.forEach(player -> {
if (predicate.test(player)) player.sendPacket(sendablePacket); if (predicate.test(player)) player.sendPacket(sendablePacket);
}); });
} }
/**
* Checks if the {@link ServerPacket} is suitable to be wrapped into a {@link CachedPacket}.
* Note: {@link ComponentHoldingServerPacket}s are not translated inside a {@link CachedPacket}.
*
* @see CachedPacket#body()
* @see PlayerSocketConnection#writePacketSync(SendablePacket, boolean)
*/
static boolean shouldUseCachePacket(final @NotNull ServerPacket packet) {
if (!MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION) return GROUPED_PACKET;
if (!(packet instanceof ComponentHoldingServerPacket holder)) return GROUPED_PACKET;
return !containsTranslatableComponents(holder);
}
private static boolean containsTranslatableComponents(final @NotNull ComponentHolder<?> holder) {
for (final Component component : holder.components()) {
if (isTranslatable(component)) return true;
}
return false;
}
private static boolean isTranslatable(final @NotNull Component component) {
if (component instanceof TranslatableComponent) return true;
final var children = component.children();
if (children.isEmpty()) return false;
for (final Component child : children) {
if (isTranslatable(child)) return true;
}
return false;
}
/** /**
* Same as {@link #sendGroupedPacket(Collection, ServerPacket, Predicate)} * Same as {@link #sendGroupedPacket(Collection, ServerPacket, Predicate)}
* but with the player validator sets to null. * but with the player validator sets to null.

View File

@ -1,10 +1,13 @@
package net.minestom.server.api; package net.minestom.server.api;
import net.kyori.adventure.translation.GlobalTranslator;
import net.minestom.server.ServerProcess; import net.minestom.server.ServerProcess;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerLoginEvent; import net.minestom.server.event.player.PlayerLoginEvent;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
import net.minestom.server.network.packet.server.SendablePacket; import net.minestom.server.network.packet.server.SendablePacket;
import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.network.player.PlayerConnection;
@ -13,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -54,12 +58,26 @@ final class TestConnectionImpl implements TestConnection {
final class PlayerConnectionImpl extends PlayerConnection { final class PlayerConnectionImpl extends PlayerConnection {
@Override @Override
public void sendPacket(@NotNull SendablePacket packet) { public void sendPacket(@NotNull SendablePacket packet) {
final var serverPacket = this.extractPacket(packet);
for (var tracker : incomingTrackers) { for (var tracker : incomingTrackers) {
final var serverPacket = SendablePacket.extractServerPacket(packet);
if (tracker.type.isAssignableFrom(serverPacket.getClass())) tracker.packets.add(serverPacket); if (tracker.type.isAssignableFrom(serverPacket.getClass())) tracker.packets.add(serverPacket);
} }
} }
private ServerPacket extractPacket(final SendablePacket packet) {
if (!(packet instanceof ServerPacket serverPacket)) return SendablePacket.extractServerPacket(packet);
final Player player = getPlayer();
if (player == null) return serverPacket;
if (MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION && serverPacket instanceof ComponentHoldingServerPacket) {
serverPacket = ((ComponentHoldingServerPacket) serverPacket).copyWithOperator(component ->
GlobalTranslator.render(component, Objects.requireNonNullElseGet(player.getLocale(), MinestomAdventure::getDefaultLocale)));
}
return serverPacket;
}
@Override @Override
public @NotNull SocketAddress getRemoteAddress() { public @NotNull SocketAddress getRemoteAddress() {
return new InetSocketAddress("localhost", 25565); return new InetSocketAddress("localhost", 25565);

View File

@ -0,0 +1,69 @@
package net.minestom.server.utils;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.translation.GlobalTranslator;
import net.kyori.adventure.translation.TranslationRegistry;
import net.minestom.server.adventure.MinestomAdventure;
import net.minestom.server.api.Env;
import net.minestom.server.api.EnvTest;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.message.ChatPosition;
import net.minestom.server.network.packet.server.play.ChatMessagePacket;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.text.MessageFormat;
import java.util.List;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
@EnvTest
public class TranslationIntegrationTest {
@BeforeAll
static void translator() {
final var translator = TranslationRegistry.create(Key.key("test.reg"));
translator.register("test.key", MinestomAdventure.getDefaultLocale(), new MessageFormat("This is a test message", MinestomAdventure.getDefaultLocale()));
GlobalTranslator.translator().addSource(translator);
}
@Test
public void testTranslationEnabled(final Env env) {
final var instance = env.createFlatInstance();
final var connection = env.createConnection();
final var player = connection.connect(instance, new Pos(0, 40, 0)).join();
final var collector = connection.trackIncoming(ChatMessagePacket.class);
MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION = true;
final var message = Component.translatable("test.key");
final var packet = new ChatMessagePacket(message, ChatPosition.CHAT, UUID.randomUUID());
PacketUtils.sendGroupedPacket(List.of(player), packet);
// the message should not be changed if translations are enabled.
// the translation of the message itself will be proceeded in PlayerConnectionImpl class
collector.assertSingle(received -> {
assertNotEquals(message, received.message());
});
}
@Test
public void testTranslationDisabled(final Env env) {
final var instance = env.createFlatInstance();
final var connection = env.createConnection();
final var player = connection.connect(instance, new Pos(0, 40, 0)).join();
final var collector = connection.trackIncoming(ChatMessagePacket.class);
MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION = false;
final var message = Component.translatable("test.key");
final var packet = new ChatMessagePacket(message, ChatPosition.CHAT, UUID.randomUUID());
PacketUtils.sendGroupedPacket(List.of(player), packet);
collector.assertSingle(received -> {
assertEquals(message, received.message());
});
}
}