feat: Introduce UserLocaleProvider implementation for Spigot, Velocity, and Standalone platforms

This commit is contained in:
huanmeng-qwq 2025-07-21 22:50:10 +08:00
parent 9ea8e9c1b4
commit acbb438325
No known key found for this signature in database
GPG key ID: A282328441529B42
5 changed files with 132 additions and 10 deletions

View file

@ -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<JavaPlugin> {
private SpigotEntityLibAPI api;
private UserLocaleProvider userLocaleProvider = new SpigotPlayerLocaleProvider();
public SpigotEntityLibPlatform(@NotNull JavaPlugin plugin) {
super(plugin);
@ -36,7 +30,7 @@ public class SpigotEntityLibPlatform extends AbstractPlatform<JavaPlugin> {
this.api.onLoad();
this.api.onEnable();
if (settings.shouldUseBstats()) {
PacketEventsAPI<Plugin> pe = (PacketEventsAPI<Plugin>)api.getPacketEvents();
PacketEventsAPI<Plugin> pe = (PacketEventsAPI<Plugin>) 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<JavaPlugin> {
public String getName() {
return "Spigot";
}
@Override
public @NotNull UserLocaleProvider getUserLocaleProvider() {
return userLocaleProvider;
}
@Override
public void setUserLocaleProvider(@NotNull final UserLocaleProvider provider) {
this.userLocaleProvider = provider;
}
}

View file

@ -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:
* <a href="https://github.com/MegavexNetwork/scoreboard-library/blob/bc8e3c2d2ecf9973ec0d6bb8ae4af94ed008b360/commons/src/main/java/net/megavex/scoreboardlibrary/implementation/commons/LocaleProvider.java">LocaleProvider</a>
* Modified and adapted for use in EntityLib.
*/
public class SpigotPlayerLocaleProvider implements UserLocaleProvider {
private static final Locale DEFAULT_LOCALE = Locale.US;
private static final Function<Player, Locale> 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<Player, Locale> 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");
}
}
}

View file

@ -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<Object> {
private StandaloneEntityLibApi api;
private UserLocaleProvider userLocaleProvider = (user) -> Locale.US;
public StandaloneEntityLibPlatform() {
super(null);
@ -34,4 +37,14 @@ public class StandaloneEntityLibPlatform extends AbstractPlatform<Object> {
public String getName() {
return "Standalone";
}
@Override
public @NotNull UserLocaleProvider getUserLocaleProvider() {
return userLocaleProvider;
}
@Override
public void setUserLocaleProvider(@NotNull final UserLocaleProvider provider) {
this.userLocaleProvider = provider;
}
}

View file

@ -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<ProxyServer> {
private VelocityEntityLibAPI api;
private UserLocaleProvider userLocaleProvider;
private Object plugin;
public VelocityEntityLibPlatform(Object plugin, ProxyServer handle) {
@ -54,4 +56,14 @@ public class VelocityEntityLibPlatform extends AbstractPlatform<ProxyServer> {
public String getName() {
return "Velocity";
}
@Override
public @NotNull UserLocaleProvider getUserLocaleProvider() {
return userLocaleProvider;
}
@Override
public void setUserLocaleProvider(final UserLocaleProvider userLocaleProvider) {
this.userLocaleProvider = userLocaleProvider;
}
}

View file

@ -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);
}
}