diff --git a/bukkit/src/main/java/co/aikar/commands/ACFBukkitLocalesListener.java b/bukkit/src/main/java/co/aikar/commands/ACFBukkitLocalesListener.java new file mode 100644 index 00000000..ae7c8098 --- /dev/null +++ b/bukkit/src/main/java/co/aikar/commands/ACFBukkitLocalesListener.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016-2025 Daniel Ennis (Aikar) - MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package co.aikar.commands; + +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerLocaleChangeEvent; + +import java.util.Locale; + +class ACFBukkitLocalesListener implements Listener { + + private final BukkitCommandManager manager; + + ACFBukkitLocalesListener(BukkitCommandManager manager) { + this.manager = manager; + } + + @EventHandler + void onLocaleChange(PlayerLocaleChangeEvent event) { + if (!manager.autoDetectFromClient) { + return; + } + Player player = event.getPlayer(); + Locale locale = null; + try { + locale = event.locale(); + } catch (NoSuchMethodError ignored) { + if (!event.getLocale().equals(manager.issuersLocaleString.get(player.getUniqueId()))) { + locale = ACFBukkitUtil.stringToLocale(event.getLocale()); + } + } + if (locale == null) { + return; + } + manager.issuersLocaleString.put(player.getUniqueId(), locale.toString()); + manager.setPlayerLocale(player, locale); + } +} diff --git a/bukkit/src/main/java/co/aikar/commands/ACFBukkitUtil.java b/bukkit/src/main/java/co/aikar/commands/ACFBukkitUtil.java index a32c4f9d..d9140c3c 100644 --- a/bukkit/src/main/java/co/aikar/commands/ACFBukkitUtil.java +++ b/bukkit/src/main/java/co/aikar/commands/ACFBukkitUtil.java @@ -38,6 +38,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -326,4 +327,9 @@ public class ACFBukkitUtil { static boolean isValidItem(ItemStack item) { return item != null && item.getType() != Material.AIR && item.getAmount() > 0; } + + public static Locale stringToLocale(String locale) { + String[] split = ACFPatterns.UNDERSCORE.split(locale); + return split.length > 1 ? new Locale(split[0], split[1]) : new Locale(split[0]); + } } diff --git a/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java b/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java index d2471303..1663aca7 100755 --- a/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java +++ b/bukkit/src/main/java/co/aikar/commands/BukkitCommandManager.java @@ -128,12 +128,20 @@ public class BukkitCommandManager extends CommandManager< Bukkit.getPluginManager().registerEvents(new ACFBukkitListener(this, plugin), plugin); getLocales(); // auto load locales - scheduler.createLocaleTask(plugin, () -> { - if (this.cantReadLocale || !this.autoDetectFromClient) { - return; - } - Bukkit.getOnlinePlayers().forEach(this::readPlayerLocale); - }, 30, 30); + + try { + // Use new event if available for newer minecraft versions + Class.forName("org.bukkit.event.player.PlayerLocaleChangeEvent"); + Bukkit.getPluginManager().registerEvents(new ACFBukkitLocalesListener(this), plugin); + } catch (ClassNotFoundException ignore) { + // Fallback to locale detection with reflection for older minecraft versions + scheduler.createLocaleTask(plugin, () -> { + if (this.cantReadLocale || !this.autoDetectFromClient) { + return; + } + Bukkit.getOnlinePlayers().forEach(this::readPlayerLocale); + }, 30, 30); + } this.validNamePredicate = ACFBukkitUtil::isValidName; @@ -335,8 +343,7 @@ public class BukkitCommandManager extends CommandManager< } if (localeString instanceof String) { if (!localeString.equals(issuersLocaleString.get(player.getUniqueId()))) { - String[] split = ACFPatterns.UNDERSCORE.split((String) localeString); - locale = split.length > 1 ? new Locale(split[0], split[1]) : new Locale(split[0]); + locale = ACFBukkitUtil.stringToLocale((String) localeString); } } }