diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java index 6c9a2cc..34c7a7d 100644 --- a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java +++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotEntityLibPlatform.java @@ -5,23 +5,17 @@ import io.github.retrooper.packetevents.bstats.bukkit.Metrics; import io.github.retrooper.packetevents.bstats.charts.SimplePie; import me.tofaa.entitylib.APIConfig; import me.tofaa.entitylib.EntityLib; +import me.tofaa.entitylib.UserLocaleProvider; import me.tofaa.entitylib.common.AbstractPlatform; -import me.tofaa.entitylib.utils.ConcurrentWeakIdentityHashMap; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.entity.Entity; +import java.util.logging.Logger; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; -import java.util.logging.Logger; -import java.util.stream.Stream; public class SpigotEntityLibPlatform extends AbstractPlatform { private SpigotEntityLibAPI api; + private UserLocaleProvider userLocaleProvider = new SpigotPlayerLocaleProvider(); public SpigotEntityLibPlatform(@NotNull JavaPlugin plugin) { super(plugin); @@ -36,7 +30,7 @@ public class SpigotEntityLibPlatform extends AbstractPlatform { this.api.onLoad(); this.api.onEnable(); if (settings.shouldUseBstats()) { - PacketEventsAPI pe = (PacketEventsAPI)api.getPacketEvents(); + PacketEventsAPI pe = (PacketEventsAPI) api.getPacketEvents(); Metrics metrics = new Metrics(pe.getPlugin(), 21916); metrics.addCustomChart(new SimplePie("entitylib-version", () -> EntityLib.getVersion().toString())); } @@ -52,4 +46,14 @@ public class SpigotEntityLibPlatform extends AbstractPlatform { public String getName() { return "Spigot"; } + + @Override + public @NotNull UserLocaleProvider getUserLocaleProvider() { + return userLocaleProvider; + } + + @Override + public void setUserLocaleProvider(@NotNull final UserLocaleProvider provider) { + this.userLocaleProvider = provider; + } } diff --git a/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotPlayerLocaleProvider.java b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotPlayerLocaleProvider.java new file mode 100644 index 0000000..a6d30ac --- /dev/null +++ b/platforms/spigot/src/main/java/me/tofaa/entitylib/spigot/SpigotPlayerLocaleProvider.java @@ -0,0 +1,73 @@ +package me.tofaa.entitylib.spigot; + +import me.tofaa.entitylib.UserLocaleProvider; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Locale; +import java.util.UUID; +import java.util.function.Function; +import net.kyori.adventure.translation.Translator; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + + +/** + * This implementation is based on code from the scoreboard-library project: + * LocaleProvider + * Modified and adapted for use in EntityLib. + */ +public class SpigotPlayerLocaleProvider implements UserLocaleProvider { + private static final Locale DEFAULT_LOCALE = Locale.US; + private static final Function provider = get(); + + @Override + public Locale locale(final UUID user) { + final Player player = Bukkit.getPlayer(user); + return player == null ? DEFAULT_LOCALE : provider.apply(player); + } + + private static @NotNull Function get() { + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + try { + MethodHandle adventureMethod = lookup.findVirtual(Player.class, "locale", MethodType.methodType(Locale.class)); + return player -> { + try { + return (Locale) adventureMethod.invokeExact(player); + } catch (Throwable e) { + throw new RuntimeException(e); + } + }; + } catch (IllegalAccessException | NoSuchMethodException ignored) { + } + + MethodType methodType = MethodType.methodType(String.class); + try { + MethodHandle legacySpigotMethod = lookup.findVirtual(Player.Spigot.class, "getLocale", methodType); + return player -> { + try { + Locale locale = Translator.parseLocale((String) legacySpigotMethod.invokeExact(player.spigot())); + return locale == null ? DEFAULT_LOCALE : locale; + } catch (Throwable e) { + throw new RuntimeException(e); + } + }; + } catch (IllegalAccessException | NoSuchMethodException ignored) { + } + + try { + MethodHandle legacyMethod = lookup.findVirtual(Player.class, "getLocale", methodType); + return player -> { + try { + Locale locale = Translator.parseLocale((String) legacyMethod.invokeExact(player)); + return locale == null ? DEFAULT_LOCALE : locale; + } catch (Throwable e) { + throw new RuntimeException(e); + } + }; + } catch (IllegalAccessException | NoSuchMethodException ignored) { + throw new RuntimeException("No way to get players locale found"); + } + } +} diff --git a/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/StandaloneEntityLibPlatform.java b/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/StandaloneEntityLibPlatform.java index 971eb56..b26e2e1 100644 --- a/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/StandaloneEntityLibPlatform.java +++ b/platforms/standalone/src/main/java/me/tofaa/entitylib/standalone/StandaloneEntityLibPlatform.java @@ -2,13 +2,16 @@ package me.tofaa.entitylib.standalone; import me.tofaa.entitylib.APIConfig; import me.tofaa.entitylib.EntityLibAPI; +import me.tofaa.entitylib.UserLocaleProvider; import me.tofaa.entitylib.common.AbstractPlatform; +import java.util.Locale; import org.jetbrains.annotations.NotNull; public class StandaloneEntityLibPlatform extends AbstractPlatform { private StandaloneEntityLibApi api; + private UserLocaleProvider userLocaleProvider = (user) -> Locale.US; public StandaloneEntityLibPlatform() { super(null); @@ -34,4 +37,14 @@ public class StandaloneEntityLibPlatform extends AbstractPlatform { public String getName() { return "Standalone"; } + + @Override + public @NotNull UserLocaleProvider getUserLocaleProvider() { + return userLocaleProvider; + } + + @Override + public void setUserLocaleProvider(@NotNull final UserLocaleProvider provider) { + this.userLocaleProvider = provider; + } } diff --git a/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityEntityLibPlatform.java b/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityEntityLibPlatform.java index 815441c..b0e96a9 100644 --- a/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityEntityLibPlatform.java +++ b/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityEntityLibPlatform.java @@ -9,6 +9,7 @@ import com.velocitypowered.api.proxy.ProxyServer; import io.github.retrooper.packetevents.velocity.factory.VelocityPacketEventsBuilder; import me.tofaa.entitylib.APIConfig; import me.tofaa.entitylib.EntityLibAPI; +import me.tofaa.entitylib.UserLocaleProvider; import me.tofaa.entitylib.common.AbstractPlatform; import org.jetbrains.annotations.NotNull; @@ -16,6 +17,7 @@ import java.util.logging.Logger; public class VelocityEntityLibPlatform extends AbstractPlatform { private VelocityEntityLibAPI api; + private UserLocaleProvider userLocaleProvider; private Object plugin; public VelocityEntityLibPlatform(Object plugin, ProxyServer handle) { @@ -54,4 +56,14 @@ public class VelocityEntityLibPlatform extends AbstractPlatform { public String getName() { return "Velocity"; } + + @Override + public @NotNull UserLocaleProvider getUserLocaleProvider() { + return userLocaleProvider; + } + + @Override + public void setUserLocaleProvider(final UserLocaleProvider userLocaleProvider) { + this.userLocaleProvider = userLocaleProvider; + } } diff --git a/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityPlayerLocaleProvider.java b/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityPlayerLocaleProvider.java new file mode 100644 index 0000000..5d9268a --- /dev/null +++ b/platforms/velocity/src/main/java/me/tofaa/entitylib/velocity/VelocityPlayerLocaleProvider.java @@ -0,0 +1,20 @@ +package me.tofaa.entitylib.velocity; + +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import me.tofaa.entitylib.UserLocaleProvider; +import java.util.Locale; +import java.util.UUID; + +public class VelocityPlayerLocaleProvider implements UserLocaleProvider { + private final ProxyServer proxyServer; + + public VelocityPlayerLocaleProvider(final ProxyServer proxyServer) { + this.proxyServer = proxyServer; + } + + @Override + public Locale locale(final UUID user) { + return proxyServer.getPlayer(user).map(Player::getEffectiveLocale).orElse(Locale.US); + } +}