forked from GeyserMC/Geyser
Introduce CommandSender.getLocale() (#1431)
* Introduce CommandSender.getLocale() This allows Geyser-specific commands (e.g. `/geyser help`) to be displayed in the (Java or Bedrock) player's default language, which stops those commands from simply being displayed in the default locale. * Tweak Javadoc * Set CommandManager's GeyserConnector to final * Clean up
This commit is contained in:
parent
9b46bf8bc9
commit
045c0e0637
37 changed files with 212 additions and 120 deletions
|
@ -25,17 +25,20 @@
|
|||
|
||||
package org.geysermc.platform.bungeecord.command;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BungeeCommandSender implements CommandSender {
|
||||
|
||||
private net.md_5.bungee.api.CommandSender handle;
|
||||
private final net.md_5.bungee.api.CommandSender handle;
|
||||
|
||||
public BungeeCommandSender(net.md_5.bungee.api.CommandSender handle) {
|
||||
this.handle = handle;
|
||||
// Ensure even Java players' languages are loaded
|
||||
LanguageUtils.loadGeyserLocale(getLocale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -51,4 +54,14 @@ public class BungeeCommandSender implements CommandSender {
|
|||
public boolean isConsole() {
|
||||
return !(handle instanceof ProxiedPlayer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocale() {
|
||||
if (handle instanceof ProxiedPlayer) {
|
||||
ProxiedPlayer player = (ProxiedPlayer) handle;
|
||||
String locale = player.getLocale().getLanguage() + "_" + player.getLocale().getCountry();
|
||||
return LanguageUtils.formatLocale(locale);
|
||||
}
|
||||
return LanguageUtils.getDefaultLocale();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,10 @@ package org.geysermc.platform.bungeecord.command;
|
|||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -41,7 +38,7 @@ import java.util.Arrays;
|
|||
|
||||
public class GeyserBungeeCommandExecutor extends Command implements TabExecutor {
|
||||
|
||||
private GeyserConnector connector;
|
||||
private final GeyserConnector connector;
|
||||
|
||||
public GeyserBungeeCommandExecutor(GeyserConnector connector) {
|
||||
super("geyser");
|
||||
|
@ -54,14 +51,10 @@ public class GeyserBungeeCommandExecutor extends Command implements TabExecutor
|
|||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
String message = "";
|
||||
if (sender instanceof GeyserSession) {
|
||||
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||
} else {
|
||||
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
|
||||
}
|
||||
BungeeCommandSender commandSender = new BungeeCommandSender(sender);
|
||||
String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());
|
||||
|
||||
sender.sendMessage(TextComponent.fromLegacyText(ChatColor.RED + message));
|
||||
commandSender.sendMessage(ChatColor.RED + message);
|
||||
return;
|
||||
}
|
||||
getCommand(args[0]).execute(new BungeeCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.geysermc.connector.utils.FileUtils;
|
|||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor;
|
||||
import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager;
|
||||
import org.geysermc.platform.spigot.command.SpigotCommandSender;
|
||||
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
|
||||
import org.geysermc.platform.spigot.world.GeyserSpigotWorldManager;
|
||||
|
||||
|
@ -130,6 +131,9 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
|
|||
geyserLogger.debug("Legacy version of Minecraft (1.15.2 or older) detected; not using 3D biomes.");
|
||||
}
|
||||
|
||||
// Set if we need to use a different method for getting a player's locale
|
||||
SpigotCommandSender.setUseLegacyLocaleMethod(!isCompatible(Bukkit.getServer().getVersion(), "1.12.0"));
|
||||
|
||||
this.geyserWorldManager = new GeyserSpigotWorldManager(isLegacy, use3dBiomes, isViaVersion);
|
||||
GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(connector, isLegacy, isViaVersion);
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@ import org.bukkit.command.CommandSender;
|
|||
import org.bukkit.command.TabExecutor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -42,21 +41,17 @@ import java.util.List;
|
|||
@AllArgsConstructor
|
||||
public class GeyserSpigotCommandExecutor implements TabExecutor {
|
||||
|
||||
private GeyserConnector connector;
|
||||
private final GeyserConnector connector;
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
String message = "";
|
||||
if (sender instanceof GeyserSession) {
|
||||
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
|
||||
} else {
|
||||
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
|
||||
}
|
||||
SpigotCommandSender commandSender = new SpigotCommandSender(sender);
|
||||
String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());;
|
||||
|
||||
sender.sendMessage(ChatColor.RED + message);
|
||||
commandSender.sendMessage(ChatColor.RED + message);
|
||||
return true;
|
||||
}
|
||||
getCommand(args[0]).execute(new SpigotCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
|
||||
|
|
|
@ -25,15 +25,33 @@
|
|||
|
||||
package org.geysermc.platform.spigot.command;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class SpigotCommandSender implements CommandSender {
|
||||
|
||||
private org.bukkit.command.CommandSender handle;
|
||||
/**
|
||||
* Whether to use {@code Player.getLocale()} or {@code Player.spigot().getLocale()}, depending on version.
|
||||
* 1.12 or greater should not use the legacy method.
|
||||
*/
|
||||
private static boolean USE_LEGACY_METHOD = false;
|
||||
private static Method LOCALE_METHOD;
|
||||
|
||||
private final org.bukkit.command.CommandSender handle;
|
||||
private final String locale;
|
||||
|
||||
public SpigotCommandSender(org.bukkit.command.CommandSender handle) {
|
||||
this.handle = handle;
|
||||
this.locale = getSpigotLocale();
|
||||
// Ensure even Java players' languages are loaded
|
||||
LanguageUtils.loadGeyserLocale(locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -49,4 +67,49 @@ public class SpigotCommandSender implements CommandSender {
|
|||
public boolean isConsole() {
|
||||
return handle instanceof ConsoleCommandSender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if we are on pre-1.12, and therefore {@code player.getLocale()} doesn't exist and we have to get
|
||||
* {@code player.spigot().getLocale()}.
|
||||
*
|
||||
* @param useLegacyMethod if we are running pre-1.12 and therefore need to use reflection to get the player locale
|
||||
*/
|
||||
public static void setUseLegacyLocaleMethod(boolean useLegacyMethod) {
|
||||
USE_LEGACY_METHOD = useLegacyMethod;
|
||||
if (USE_LEGACY_METHOD) {
|
||||
try {
|
||||
//noinspection JavaReflectionMemberAccess - of course it doesn't exist; that's why we're doing it
|
||||
LOCALE_METHOD = Player.Spigot.class.getMethod("getLocale");
|
||||
} catch (NoSuchMethodException e) {
|
||||
GeyserConnector.getInstance().getLogger().debug("Player.Spigot.getLocale() doesn't exist? Not a big deal but if you're seeing this please report it to the developers!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* So we only have to do nasty reflection stuff once per command
|
||||
*
|
||||
* @return the locale of the Spigot player
|
||||
*/
|
||||
private String getSpigotLocale() {
|
||||
if (handle instanceof Player) {
|
||||
Player player = (Player) handle;
|
||||
if (USE_LEGACY_METHOD) {
|
||||
try {
|
||||
// sigh
|
||||
// This was the only option on older Spigot instances and now it's gone
|
||||
return (String) LOCALE_METHOD.invoke(player.spigot());
|
||||
} catch (IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
} else {
|
||||
return player.getLocale();
|
||||
}
|
||||
}
|
||||
return LanguageUtils.getDefaultLocale();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,14 +27,11 @@ package org.geysermc.platform.velocity.command;
|
|||
|
||||
import com.velocitypowered.api.command.Command;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import net.kyori.text.TextComponent;
|
||||
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.common.ChatColor;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -42,15 +39,15 @@ import java.util.Arrays;
|
|||
@AllArgsConstructor
|
||||
public class GeyserVelocityCommandExecutor implements Command {
|
||||
|
||||
private GeyserConnector connector;
|
||||
private final GeyserConnector connector;
|
||||
|
||||
@Override
|
||||
public void execute(CommandSource source, String[] args) {
|
||||
if (args.length > 0) {
|
||||
if (getCommand(args[0]) != null) {
|
||||
if (!source.hasPermission(getCommand(args[0]).getPermission())) {
|
||||
// Not ideal to use log here but we dont get a session
|
||||
source.sendMessage(TextComponent.of(ChatColor.RED + LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail")));
|
||||
CommandSender sender = new VelocityCommandSender(source);
|
||||
sender.sendMessage(ChatColor.RED + LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
|
||||
return;
|
||||
}
|
||||
getCommand(args[0]).execute(new VelocityCommandSender(source), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
|
||||
|
|
|
@ -28,17 +28,21 @@ package org.geysermc.platform.velocity.command;
|
|||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.proxy.ConsoleCommandSource;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import net.kyori.text.TextComponent;
|
||||
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.utils.LanguageUtils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class VelocityCommandSender implements CommandSender {
|
||||
|
||||
private CommandSource handle;
|
||||
private final CommandSource handle;
|
||||
|
||||
public VelocityCommandSender(CommandSource handle) {
|
||||
this.handle = handle;
|
||||
// Ensure even Java players' languages are loaded
|
||||
LanguageUtils.loadGeyserLocale(getLocale());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -59,4 +63,13 @@ public class VelocityCommandSender implements CommandSender {
|
|||
public boolean isConsole() {
|
||||
return handle instanceof ConsoleCommandSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocale() {
|
||||
if (handle instanceof Player) {
|
||||
Locale locale = ((Player) handle).getPlayerSettings().getLocale();
|
||||
return LanguageUtils.formatLocale(locale.getLanguage() + "_" + locale.getCountry());
|
||||
}
|
||||
return LanguageUtils.getDefaultLocale();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue