From 9ea8e9c1b4af2f740f317761fbb2de9a852ce71f Mon Sep 17 00:00:00 2001 From: huanmeng-qwq <1871735932@qq.com> Date: Mon, 21 Jul 2025 22:26:51 +0800 Subject: [PATCH] feat: Add user locale handling and metadata translation support --- .../java/me/tofaa/entitylib/EntityLibAPI.java | 2 ++ .../java/me/tofaa/entitylib/Platform.java | 13 +++++++ .../tofaa/entitylib/UserLocaleProvider.java | 8 +++++ .../me/tofaa/entitylib/utils/PacketUtil.java | 34 +++++++++++++++++++ .../entitylib/wrapper/WrapperEntity.java | 31 +++++++++++++---- .../common/AbstractEntityLibAPI.java | 6 ++++ 6 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 api/src/main/java/me/tofaa/entitylib/UserLocaleProvider.java create mode 100644 api/src/main/java/me/tofaa/entitylib/utils/PacketUtil.java diff --git a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java index c6041f7..77de149 100644 --- a/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java +++ b/api/src/main/java/me/tofaa/entitylib/EntityLibAPI.java @@ -53,4 +53,6 @@ public interface EntityLibAPI { @NotNull EntityContainer getDefaultContainer(); + @NotNull + UserLocaleProvider getUserLocaleProvider(); } diff --git a/api/src/main/java/me/tofaa/entitylib/Platform.java b/api/src/main/java/me/tofaa/entitylib/Platform.java index 62accad..fa75430 100644 --- a/api/src/main/java/me/tofaa/entitylib/Platform.java +++ b/api/src/main/java/me/tofaa/entitylib/Platform.java @@ -26,6 +26,13 @@ public interface Platform

{ */ @NotNull EntityUuidProvider getEntityUuidProvider(); + /** + * Gets the provider responsible for retrieving the locale of a user. + * + * @return a non-null {@link UserLocaleProvider} instance. + */ + @NotNull UserLocaleProvider getUserLocaleProvider(); + /** * Sets the entityId integer provider. This can be provided by a platform if needed. * @param provider the entityId integer provider. @@ -38,6 +45,12 @@ public interface Platform

{ */ void setEntityUuidProvider(@NotNull EntityUuidProvider provider); + /** + * Sets the provider responsible for retrieving the locale of a user. + * + * @param provider the {@link UserLocaleProvider} instance to be set. Must not be null. + */ + void setUserLocaleProvider(@NotNull UserLocaleProvider provider); /** * @return the logger EntityLib uses internally. diff --git a/api/src/main/java/me/tofaa/entitylib/UserLocaleProvider.java b/api/src/main/java/me/tofaa/entitylib/UserLocaleProvider.java new file mode 100644 index 0000000..54c542d --- /dev/null +++ b/api/src/main/java/me/tofaa/entitylib/UserLocaleProvider.java @@ -0,0 +1,8 @@ +package me.tofaa.entitylib; + +import java.util.Locale; +import java.util.UUID; + +public interface UserLocaleProvider { + Locale locale(UUID user); +} diff --git a/api/src/main/java/me/tofaa/entitylib/utils/PacketUtil.java b/api/src/main/java/me/tofaa/entitylib/utils/PacketUtil.java new file mode 100644 index 0000000..9e3b130 --- /dev/null +++ b/api/src/main/java/me/tofaa/entitylib/utils/PacketUtil.java @@ -0,0 +1,34 @@ +package me.tofaa.entitylib.utils; + +import com.github.retrooper.packetevents.protocol.entity.data.EntityData; +import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata; +import me.tofaa.entitylib.EntityLib; +import java.util.Locale; +import java.util.Optional; +import java.util.UUID; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.translation.GlobalTranslator; + +public class PacketUtil { + private PacketUtil() { + } + + public static void renderPacket(UUID user, WrapperPlayServerEntityMetadata metadata) { + Locale locale = EntityLib.getApi().getUserLocaleProvider().locale(user); + for (final EntityData entityData : metadata.getEntityMetadata()) { + if (entityData.getType() == EntityDataTypes.ADV_COMPONENT) { + Component component = (Component) entityData.getValue(); + final Component rendered = GlobalTranslator.render(component, locale); + ((EntityData) entityData).setValue(rendered); + } else if (entityData.getType() == EntityDataTypes.OPTIONAL_ADV_COMPONENT) { + final Optional optional = (Optional) entityData.getValue(); + if (optional.isPresent()) { + final Component component = optional.get(); + final Component rendered = GlobalTranslator.render(component, locale); + ((EntityData>) entityData).setValue(Optional.of(rendered)); + } + } + } + } +} diff --git a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java index 40c8de9..1e37128 100644 --- a/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java +++ b/api/src/main/java/me/tofaa/entitylib/wrapper/WrapperEntity.java @@ -5,25 +5,39 @@ import com.github.retrooper.packetevents.protocol.player.User; import com.github.retrooper.packetevents.protocol.world.Location; import com.github.retrooper.packetevents.util.Vector3d; import com.github.retrooper.packetevents.wrapper.PacketWrapper; -import com.github.retrooper.packetevents.wrapper.play.server.*; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBundle; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityHeadLook; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityVelocity; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPassengers; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity; +import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage; import me.tofaa.entitylib.EntityLib; import me.tofaa.entitylib.container.EntityContainer; import me.tofaa.entitylib.meta.EntityMeta; import me.tofaa.entitylib.meta.types.ObjectData; import me.tofaa.entitylib.tick.Tickable; +import me.tofaa.entitylib.utils.PacketUtil; import me.tofaa.entitylib.ve.ViewerRule; import me.tofaa.entitylib.wrapper.spawning.SpawnPacketProvider; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; import net.kyori.adventure.text.Component; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.function.Consumer; - public class WrapperEntity implements Tickable { private final UUID uuid; private final int entityId; @@ -510,6 +524,11 @@ public class WrapperEntity implements Tickable { return; } + // Special handling for entity metadata packets to support `GlobalTranslator` functionality and component rendering + if (wrapper instanceof WrapperPlayServerEntityMetadata) { + PacketUtil.renderPacket(user, (WrapperPlayServerEntityMetadata) wrapper); + } + EntityLib.getApi().getPacketEvents().getProtocolManager().sendPacket(channel, wrapper); } diff --git a/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java b/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java index bfee9b4..dd2922b 100644 --- a/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java +++ b/common/src/main/java/me/tofaa/entitylib/common/AbstractEntityLibAPI.java @@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEventsAPI; import me.tofaa.entitylib.APIConfig; import me.tofaa.entitylib.EntityLibAPI; import me.tofaa.entitylib.Platform; +import me.tofaa.entitylib.UserLocaleProvider; import me.tofaa.entitylib.container.EntityContainer; import me.tofaa.entitylib.tick.TickContainer; import me.tofaa.entitylib.wrapper.WrapperEntity; @@ -63,4 +64,9 @@ public abstract class AbstractEntityLibAPI implements EntityLibAPI { public @NotNull Collection> getTickContainers() { return tickContainers; } + + @Override + public @NotNull UserLocaleProvider getUserLocaleProvider() { + return platform.getUserLocaleProvider(); + } }