(Bug?) Translation keys in `VelocityBrigadierMessage` are sent as their literal key rather than allowing the client to translate
willkroboth opened this issue · comments
Reproduction
I created a Velocity server with a Paper backend server. On Velocity, I have this plugin:
public class VelocityTestPlugin {
@Inject
private ProxyServer server;
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
server.getCommandManager().register(new BrigadierCommand(
LiteralArgumentBuilder.<CommandSource>literal("velocityCommand").then(
RequiredArgumentBuilder.<CommandSource, String>argument("player", StringArgumentType.word())
.suggests((context, builder) -> {
server.getAllPlayers().stream().map(Player::getUsername).forEach(builder::suggest);
return builder.buildFuture();
})
.executes(context -> {
String playerName = context.getArgument("player", String.class);
Optional<Player> optionalPlayer = server.getPlayer(playerName);
if(optionalPlayer.isEmpty())
throw new SimpleCommandExceptionType(VelocityBrigadierMessage.tooltip(Component.translatable("argument.player.unknown"))).create();
optionalPlayer.get().sendMessage(Component.text("You were the target of the command"));
return 1;
})
)
));
}
}
This plugin registers a BrigadierCommand
that attempts to get a Player
object from a string. If a player cannot be found for the given String, the command throws an error using one of Minecraft's language codes, argument.player.unknown
.
On Paper, I have this plugin:
public final class BukkitTestPlugin extends JavaPlugin implements Listener {
@Override
public void onEnable() {
getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, event -> {
Commands commands = event.registrar();
commands.register(
Commands.literal("paperCommand").then(
Commands.argument("player", StringArgumentType.word())
.suggests((context, builder) -> {
Bukkit.getOnlinePlayers().stream().map(Player::getName).forEach(builder::suggest);
return builder.buildFuture();
})
.executes(context -> {
String playerName = context.getArgument("player", String.class);
Player player = Bukkit.getPlayer(playerName);
if(player == null)
throw new SimpleCommandExceptionType(PaperBrigadier.message(Component.translatable("argument.player.unknown"))).create();
player.sendMessage(Component.text("You were the target of the command"));
return 1;
})
).build()
);
});
}
}
This uses API from PaperMC/Paper#8235 to register a command that is basically the same as the one on Velocity.
Observed results
When I join the server, I get these results when running the commands (I switched my client language from English to Spanish):
When running /velocitycommand notPlayer
, I expect the key argument.player.unknown
to be translated to the client's language, which is what happens when running papercommand notPlayer
. Instead, the player is sent the literal text argument.player.unknown
.
I believe this comes from line 235 in VelocityCommandManager
:
CommandSyntaxException#getMessage
ends up flattening the Component held by VelocityBrigadierMessage
into plain text (see here).
Instead, I believe this code should use CommandSyntaxException#getRawMessage
. If the (Message e.getRawMessage()) instanceof VelocityBrigadierMessage
, then the Component held by VelocityBrigadierMessage
should be sent directly to the client. If that is a TranslateableComponent
, then its key should be sent to the client for them to deal with as appropriate https://wiki.vg/Text_formatting#Translatable_content.
I'm not very familiar with how translated messages work on Velocity, but I expect that these equivalent commands on Paper and Velocity should work the same.