diff --git a/src/main/java/fr/xephi/authme/listener/protocollib/I18NGetLocalePacketAdapter.java b/src/main/java/fr/xephi/authme/listener/protocollib/I18NGetLocalePacketAdapter.java new file mode 100644 index 00000000..60148ba5 --- /dev/null +++ b/src/main/java/fr/xephi/authme/listener/protocollib/I18NGetLocalePacketAdapter.java @@ -0,0 +1,36 @@ +package fr.xephi.authme.listener.protocollib; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.util.message.I18NUtils; + +import java.util.UUID; + +class I18NGetLocalePacketAdapter extends PacketAdapter { + + I18NGetLocalePacketAdapter(AuthMe plugin) { + super(plugin, ListenerPriority.NORMAL, PacketType.Play.Client.SETTINGS); + } + + @Override + public void onPacketReceiving(PacketEvent event) { + if (event.getPacketType() == PacketType.Play.Client.SETTINGS) { + String locale = event.getPacket().getStrings().read(0).toLowerCase(); + UUID uuid = event.getPlayer().getUniqueId(); + + I18NUtils.addLocale(uuid, locale); + } + } + + public void register() { + ProtocolLibrary.getProtocolManager().addPacketListener(this); + } + + public void unregister() { + ProtocolLibrary.getProtocolManager().removePacketListener(this); + } +} diff --git a/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java b/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java index 02407757..60fabc09 100644 --- a/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java +++ b/src/main/java/fr/xephi/authme/listener/protocollib/ProtocolLibService.java @@ -9,7 +9,9 @@ import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.output.ConsoleLoggerFactory; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; +import fr.xephi.authme.util.Utils; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -22,10 +24,12 @@ public class ProtocolLibService implements SettingsDependent { /* Packet Adapters */ private InventoryPacketAdapter inventoryPacketAdapter; private TabCompletePacketAdapter tabCompletePacketAdapter; + private I18NGetLocalePacketAdapter i18nGetLocalePacketAdapter; /* Settings */ private boolean protectInvBeforeLogin; private boolean denyTabCompleteBeforeLogin; + private boolean i18nMessagesSending; /* Service */ private boolean isEnabled; @@ -58,6 +62,10 @@ public class ProtocolLibService implements SettingsDependent { logger.warning("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it..."); } + if (i18nMessagesSending) { + logger.warning("WARNING! The i18n Messages feature requires ProtocolLib on lower version (< 1.15.2)! Disabling it..."); + } + this.isEnabled = false; return; } @@ -84,6 +92,16 @@ public class ProtocolLibService implements SettingsDependent { tabCompletePacketAdapter = null; } + if (i18nMessagesSending) { + if (i18nGetLocalePacketAdapter == null) { + i18nGetLocalePacketAdapter = new I18NGetLocalePacketAdapter(plugin); + i18nGetLocalePacketAdapter.register(); + } + } else if (i18nGetLocalePacketAdapter != null) { + i18nGetLocalePacketAdapter.unregister(); + i18nGetLocalePacketAdapter = null; + } + this.isEnabled = true; } @@ -101,6 +119,10 @@ public class ProtocolLibService implements SettingsDependent { tabCompletePacketAdapter.unregister(); tabCompletePacketAdapter = null; } + if (i18nGetLocalePacketAdapter != null) { + i18nGetLocalePacketAdapter.unregister(); + i18nGetLocalePacketAdapter = null; + } } /** @@ -120,6 +142,7 @@ public class ProtocolLibService implements SettingsDependent { this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN); this.denyTabCompleteBeforeLogin = settings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN); + this.i18nMessagesSending = settings.getProperty(PluginSettings.I18N_MESSAGES) && Utils.majorVersion <= 15; //it was true and will be deactivated now, so we need to restore the inventory for every player if (oldProtectInventory && !protectInvBeforeLogin && inventoryPacketAdapter != null) { diff --git a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java index 7a98862a..3a2eca41 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java @@ -21,7 +21,8 @@ public final class PluginSettings implements SettingsHolder { @Comment({ "Send i18n messages to player based on their client settings, this option will override `settings.messagesLanguage`", - "This will not affect language of authme help command." + "(Requires Protocollib if server version under 1.15.2)", + "This will not affect language of AuthMe help command." }) public static final Property I18N_MESSAGES = newProperty("3rdPartyFeature.features.i18nMessages.enabled", false); diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index 565780ea..f3322059 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -115,5 +115,5 @@ public final class Utils { private final static int mcFirstVersion = Integer.parseInt(serverVersion[0]); public final static int majorVersion = Integer.parseInt(serverVersion[1]); - public final static int minorVersion = Integer.parseInt(serverVersion[2]); + public final static int minorVersion = serverVersion.length == 3 ? Integer.parseInt(serverVersion[2]) : 0; } diff --git a/src/main/java/fr/xephi/authme/util/message/I18NUtils.java b/src/main/java/fr/xephi/authme/util/message/I18NUtils.java index b8f11ba1..4883a0f0 100644 --- a/src/main/java/fr/xephi/authme/util/message/I18NUtils.java +++ b/src/main/java/fr/xephi/authme/util/message/I18NUtils.java @@ -5,15 +5,16 @@ import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.util.Utils; import org.bukkit.entity.Player; -import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; public class I18NUtils { - private static Method spigotGetLocale; + private static Map PLAYER_LOCALE = new ConcurrentHashMap<>(); private static final Map LOCALE_MAP = new HashMap<>(); private static final List LOCALE_LIST = Arrays.asList( "en", "bg", "de", "eo", "es", "et", "eu", "fi", "fr", "gl", "hu", "id", "it", "ja", "ko", "lt", "nl", "pl", @@ -21,13 +22,6 @@ public class I18NUtils { ); static { - try { - spigotGetLocale = Player.Spigot.class.getMethod("getLocale"); - spigotGetLocale.setAccessible(true); - } catch (NoSuchMethodException e) { - spigotGetLocale = null; - } - LOCALE_MAP.put("pt_br", "br"); LOCALE_MAP.put("cs_cz", "cz"); LOCALE_MAP.put("nds_de", "de"); @@ -40,7 +34,7 @@ public class I18NUtils { LOCALE_MAP.put("zh_cn", "zhcn"); LOCALE_MAP.put("zh_hk", "zhhk"); LOCALE_MAP.put("zh_tw", "zhtw"); - // LOCALE_MAP.put("zhmc", "zhmc"); + //LOCALE_MAP.put("zhmc", "zhmc"); } /** @@ -49,18 +43,30 @@ public class I18NUtils { * @param player The player */ public static String getLocale(Player player) { - if (Utils.majorVersion >= 12) { + if (Utils.majorVersion > 15) { return player.getLocale().toLowerCase(); } else { - try { - return ((String) spigotGetLocale.invoke(player.spigot())).toLowerCase(); - } catch (Exception e) { - e.printStackTrace(); - return null; + long startTime = System.currentTimeMillis(); + for (;;) { + if (PLAYER_LOCALE.containsKey(player.getUniqueId())) { + return PLAYER_LOCALE.get(player.getUniqueId()); + } + + if (System.currentTimeMillis() - startTime > 3000) { + return null; + } } } } + public static void addLocale(UUID uuid, String locale) { + if (PLAYER_LOCALE == null) { + PLAYER_LOCALE = new ConcurrentHashMap<>(); + } + + PLAYER_LOCALE.put(uuid, locale); + } + /** * Returns the AuthMe messages file language code, by given locale and settings. * Dreeam - Hard mapping, based on mc1.20.6, 5/29/2024