diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
index 5855fdf8e..bbe8a23aa 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
@@ -78,6 +78,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.ResourceBundle;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
@@ -90,7 +91,11 @@ import java.util.function.IntFunction;
import java.util.stream.Collectors;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
+import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
+import net.kyori.adventure.translation.GlobalTranslator;
+import net.kyori.adventure.translation.TranslationRegistry;
+import net.kyori.adventure.util.UTF8ResourceBundleControl;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.asynchttpclient.AsyncHttpClient;
@@ -193,6 +198,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
logger.info("Booting up {} {}...", version().getName(), version().getVersion());
console.setupStreams();
+ registerTranslations();
+
serverKeyPair = EncryptionUtils.createRsaKeyPair(1024);
cm.logChannelInformation();
@@ -236,6 +243,15 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
Metrics.VelocityMetrics.startMetrics(this, configuration.getMetrics());
}
+ private void registerTranslations() {
+ final TranslationRegistry translationRegistry = TranslationRegistry
+ .create(Key.key("velocity", "translations"));
+ translationRegistry.registerAll(Locale.US,
+ ResourceBundle.getBundle("com/velocitypowered/proxy/messages", Locale.US,
+ UTF8ResourceBundleControl.get()), false);
+ GlobalTranslator.get().addSource(translationRegistry);
+ }
+
@SuppressFBWarnings("DM_EXIT")
private void doStartupConfigLoad() {
try {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/CommandMessages.java b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/CommandMessages.java
new file mode 100644
index 000000000..b4a5a2130
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/CommandMessages.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.velocitypowered.proxy.command.builtin;
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.TranslatableComponent;
+import net.kyori.adventure.text.format.NamedTextColor;
+
+public class CommandMessages {
+
+ public static final TranslatableComponent PLAYERS_ONLY = Component.translatable(
+ "velocity.command.players-only", NamedTextColor.RED);
+ public static final TranslatableComponent SERVER_DOES_NOT_EXIST = Component.translatable(
+ "velocity.command.server-does-not-exist", NamedTextColor.RED);
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/GlistCommand.java b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/GlistCommand.java
index d12f33cf2..6d0f8f947 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/GlistCommand.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/GlistCommand.java
@@ -78,11 +78,7 @@ public class GlistCommand {
final CommandSource source = context.getSource();
sendTotalProxyCount(source);
source.sendMessage(Identity.nil(),
- Component.text().content("To view all players on servers, use ")
- .color(NamedTextColor.YELLOW)
- .append(Component.text("/glist all", NamedTextColor.DARK_AQUA))
- .append(Component.text(".", NamedTextColor.YELLOW))
- .build());
+ Component.translatable("velocity.command.glist-view-all", NamedTextColor.YELLOW));
return 1;
}
@@ -98,7 +94,7 @@ public class GlistCommand {
Optional registeredServer = server.server(serverName);
if (!registeredServer.isPresent()) {
source.sendMessage(Identity.nil(),
- Component.text("Server " + serverName + " doesn't exist.", NamedTextColor.RED));
+ CommandMessages.SERVER_DOES_NOT_EXIST.args(Component.text(serverName)));
return -1;
}
sendServerPlayers(source, registeredServer.get(), false);
@@ -107,10 +103,19 @@ public class GlistCommand {
}
private void sendTotalProxyCount(CommandSource target) {
+ int online = server.countConnectedPlayers();
target.sendMessage(Identity.nil(), Component.text()
- .content("There are ").color(NamedTextColor.YELLOW)
- .append(Component.text(server.connectedPlayers().size(), NamedTextColor.GREEN))
- .append(Component.text(" player(s) online.", NamedTextColor.YELLOW))
+ .append(Component.text(Integer.toString(online), NamedTextColor.GREEN))
+ .append(Component.space())
+ .append(Component.translatable(
+ online == 1
+ ? "velocity.command.glist-player-singular"
+ : "velocity.command.glist-player-plural",
+ NamedTextColor.YELLOW
+ ))
+ .append(Component.space())
+ .append(Component.translatable("velocity.command.glist-total-suffix",
+ NamedTextColor.YELLOW))
.build());
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/ServerCommand.java b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/ServerCommand.java
index 760c6b6e0..87ec2d6a6 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/ServerCommand.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/ServerCommand.java
@@ -35,6 +35,7 @@ import java.util.stream.Stream;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -53,8 +54,7 @@ public class ServerCommand implements SimpleCommand {
final String[] args = invocation.arguments();
if (!(source instanceof Player)) {
- source.sendMessage(Identity.nil(), Component.text("Only players may run this command.",
- NamedTextColor.RED));
+ source.sendMessage(Identity.nil(), CommandMessages.PLAYERS_ONLY);
return;
}
@@ -64,8 +64,8 @@ public class ServerCommand implements SimpleCommand {
String serverName = args[0];
Optional toConnect = server.server(serverName);
if (!toConnect.isPresent()) {
- player.sendMessage(Identity.nil(),
- Component.text("Server " + serverName + " doesn't exist.", NamedTextColor.RED));
+ player.sendMessage(Identity.nil(), CommandMessages.SERVER_DOES_NOT_EXIST
+ .args(Component.text(serverName)));
return;
}
@@ -78,19 +78,23 @@ public class ServerCommand implements SimpleCommand {
private void outputServerInformation(Player executor) {
String currentServer = executor.connectedServer().map(ServerConnection::serverInfo)
.map(ServerInfo::name).orElse("");
- executor.sendMessage(Identity.nil(), Component.text(
- "You are currently connected to " + currentServer + ".", NamedTextColor.YELLOW));
+ executor.sendMessage(Identity.nil(), Component.translatable(
+ "velocity.command.server-current-server",
+ NamedTextColor.YELLOW,
+ Component.text(currentServer)));
List servers = BuiltinCommandUtil.sortedServerList(server);
if (servers.size() > MAX_SERVERS_TO_LIST) {
- executor.sendMessage(Identity.nil(), Component.text(
- "Too many servers to list. Tab-complete to show all servers.", NamedTextColor.RED));
+ executor.sendMessage(Identity.nil(), Component.translatable(
+ "velocity.command.server-too-many", NamedTextColor.RED));
return;
}
// Assemble the list of servers as components
- TextComponent.Builder serverListBuilder = Component.text().content("Available servers: ")
- .color(NamedTextColor.YELLOW);
+ TextComponent.Builder serverListBuilder = Component.text()
+ .append(Component.translatable("velocity.command.server-available",
+ NamedTextColor.YELLOW))
+ .append(Component.space());
for (int i = 0; i < servers.size(); i++) {
RegisteredServer rs = servers.get(i);
serverListBuilder.append(formatServerComponent(currentServer, rs));
@@ -106,17 +110,31 @@ public class ServerCommand implements SimpleCommand {
ServerInfo serverInfo = server.serverInfo();
TextComponent serverTextComponent = Component.text(serverInfo.name());
- String playersText = server.connectedPlayers().size() + " player(s) online";
+ int connectedPlayers = server.connectedPlayers().size();
+ TranslatableComponent playersTextComponent;
+ if (connectedPlayers == 1) {
+ playersTextComponent = Component.translatable("velocity.command.server-tooltip-player-online");
+ } else {
+ playersTextComponent = Component.translatable("velocity.command.server-tooltip-players-online");
+ }
+ playersTextComponent = playersTextComponent.args(Component.text(connectedPlayers));
+
if (serverInfo.name().equals(currentPlayerServer)) {
serverTextComponent = serverTextComponent.color(NamedTextColor.GREEN)
.hoverEvent(
- showText(Component.text("Currently connected to this server\n" + playersText))
+ showText(
+ Component.translatable("velocity.command.server-tooltip-current-server")
+ .append(Component.newline())
+ .append(playersTextComponent))
);
} else {
serverTextComponent = serverTextComponent.color(NamedTextColor.GRAY)
.clickEvent(ClickEvent.runCommand("/server " + serverInfo.name()))
.hoverEvent(
- showText(Component.text("Click to connect to this server\n" + playersText))
+ showText(
+ Component.translatable("velocity.command.server-tooltip-offer-connect-server")
+ .append(Component.newline())
+ .append(playersTextComponent))
);
}
return serverTextComponent;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/VelocityCommand.java b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/VelocityCommand.java
index e7a579727..c2fee2570 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/VelocityCommand.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/command/builtin/VelocityCommand.java
@@ -17,7 +17,6 @@
package com.velocitypowered.proxy.command.builtin;
-import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -49,6 +48,7 @@ import java.util.stream.Collectors;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -180,17 +180,15 @@ public class VelocityCommand implements SimpleCommand {
public void execute(CommandSource source, String @NonNull [] args) {
try {
if (server.reloadConfiguration()) {
- source.sendMessage(Identity.nil(), Component.text(
- "Configuration reloaded.", NamedTextColor.GREEN));
+ source.sendMessage(Component.translatable("velocity.command.reload-success",
+ NamedTextColor.GREEN));
} else {
- source.sendMessage(Identity.nil(), Component.text(
- "Unable to reload your configuration. Check the console for more details.",
+ source.sendMessage(Component.translatable("velocity.command.reload-failure",
NamedTextColor.RED));
}
} catch (Exception e) {
logger.error("Unable to reload configuration", e);
- source.sendMessage(Identity.nil(), Component.text(
- "Unable to reload your configuration. Check the console for more details.",
+ source.sendMessage(Component.translatable("velocity.command.reload-failure",
NamedTextColor.RED));
}
}
@@ -219,33 +217,35 @@ public class VelocityCommand implements SimpleCommand {
ProxyVersion version = server.version();
- TextComponent velocity = Component.text().content(version.getName() + " ")
+ Component velocity = Component.text().content(version.getName() + " ")
.decoration(TextDecoration.BOLD, true)
.color(VELOCITY_COLOR)
.append(Component.text(version.getVersion()).decoration(TextDecoration.BOLD, false))
.build();
- TextComponent copyright = Component
- .text("Copyright 2018-2020 " + version.getVendor() + ". " + version.getName()
- + " is licensed under the terms of the GNU General Public License v3.");
+ Component copyright = Component
+ .translatable("velocity.command.version-copyright",
+ Component.text(version.getVendor()),
+ Component.text(version.getName()));
source.sendMessage(Identity.nil(), velocity);
source.sendMessage(Identity.nil(), copyright);
if (version.getName().equals("Velocity")) {
- TextComponent velocityWebsite = Component.text()
- .content("Visit the ")
- .append(Component.text().content("Velocity website")
+ TextComponent embellishment = Component.text()
+ .append(Component.text().content("velocitypowered.com")
.color(NamedTextColor.GREEN)
+ .decoration(TextDecoration.UNDERLINED, true)
.clickEvent(
ClickEvent.openUrl("https://www.velocitypowered.com"))
.build())
- .append(Component.text(" or the "))
- .append(Component.text().content("Velocity GitHub")
+ .append(Component.text(" - "))
+ .append(Component.text().content("GitHub")
.color(NamedTextColor.GREEN)
+ .decoration(TextDecoration.UNDERLINED, true)
.clickEvent(ClickEvent.openUrl(
"https://github.com/VelocityPowered/Velocity"))
.build())
.build();
- source.sendMessage(Identity.nil(), velocityWebsite);
+ source.sendMessage(Identity.nil(), embellishment);
}
}
@@ -274,12 +274,13 @@ public class VelocityCommand implements SimpleCommand {
int pluginCount = plugins.size();
if (pluginCount == 0) {
- source.sendMessage(Identity.nil(), Component.text(
- "No plugins installed.", NamedTextColor.YELLOW));
+ source.sendMessage(Component.translatable("velocity.command.no-plugins",
+ NamedTextColor.YELLOW));
return;
}
- TextComponent.Builder output = Component.text().content("Plugins: ")
+ TranslatableComponent.Builder output = Component.translatable()
+ .key("velocity.command.plugins-list")
.color(NamedTextColor.YELLOW);
for (int i = 0; i < pluginCount; i++) {
PluginContainer plugin = plugins.get(i);
@@ -300,15 +301,21 @@ public class VelocityCommand implements SimpleCommand {
description.url().ifPresent(url -> {
hoverText.append(Component.newline());
- hoverText.append(Component.text("Website: " + url));
+ hoverText.append(Component.translatable(
+ "velocity.command.plugin-tooltip-website",
+ Component.text(url)));
});
if (!description.authors().isEmpty()) {
hoverText.append(Component.newline());
if (description.authors().size() == 1) {
- hoverText.append(Component.text("Author: " + description.authors().get(0)));
+ hoverText.append(Component.translatable("velocity.command.plugin-tooltip-author",
+ Component.text(description.authors().get(0))));
} else {
- hoverText.append(Component.text("Authors: " + Joiner.on(", ")
- .join(description.authors())));
+ hoverText.append(
+ Component.translatable("velocity.command.plugin-tooltip-author",
+ Component.text(String.join(", ", description.authors()))
+ )
+ );
}
}
description.description().ifPresent(pdesc -> {
@@ -352,8 +359,8 @@ public class VelocityCommand implements SimpleCommand {
JsonArray connectOrder = new JsonArray();
List attemptedConnectionOrder = ImmutableList.copyOf(
server.configuration().getAttemptConnectionOrder());
- for (int i = 0; i < attemptedConnectionOrder.size(); i++) {
- connectOrder.add(attemptedConnectionOrder.get(i));
+ for (String s : attemptedConnectionOrder) {
+ connectOrder.add(s);
}
JsonObject proxyConfig = InformationUtils.collectProxyConfig(server.configuration());
@@ -446,7 +453,7 @@ public class VelocityCommand implements SimpleCommand {
e.getCause().printStackTrace();
} catch (JsonParseException e) {
source.sendMessage(Component.text()
- .content("An error occurred on the Velocity-servers and the dump could not "
+ .content("An error occurred on the Velocity servers and the dump could not "
+ "be completed. Please contact the Velocity staff about this problem. "
+ "If you do, provide the details about this error from the Velocity "
+ "console or server log.")
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java
index 033dd188f..deefcd99b 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/config/VelocityConfiguration.java
@@ -45,7 +45,6 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
-import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.apache.logging.log4j.LogManager;
@@ -72,25 +71,23 @@ public class VelocityConfiguration implements ProxyConfig {
@Expose private final Advanced advanced;
@Expose private final Query query;
private final Metrics metrics;
- private final Messages messages;
private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent;
private @Nullable Favicon favicon;
private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced,
- Query query, Metrics metrics, Messages messages) {
+ Query query, Metrics metrics) {
this.servers = servers;
this.forcedHosts = forcedHosts;
this.advanced = advanced;
this.query = query;
this.metrics = metrics;
- this.messages = messages;
}
private VelocityConfiguration(String bind, String motd, int showMaxPlayers, boolean onlineMode,
boolean preventClientProxyConnections, boolean announceForge,
PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret,
boolean onlineModeKickExistingPlayers, PingPassthroughMode pingPassthrough, Servers servers,
- ForcedHosts forcedHosts, Advanced advanced, Query query, Metrics metrics, Messages messages) {
+ ForcedHosts forcedHosts, Advanced advanced, Query query, Metrics metrics) {
this.bind = bind;
this.motd = motd;
this.showMaxPlayers = showMaxPlayers;
@@ -106,7 +103,6 @@ public class VelocityConfiguration implements ProxyConfig {
this.advanced = advanced;
this.query = query;
this.metrics = metrics;
- this.messages = messages;
}
/**
@@ -373,10 +369,6 @@ public class VelocityConfiguration implements ProxyConfig {
return advanced.isLogCommandExecutions();
}
- public Messages getMessages() {
- return messages;
- }
-
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
@@ -450,7 +442,6 @@ public class VelocityConfiguration implements ProxyConfig {
CommentedConfig advancedConfig = config.get("advanced");
CommentedConfig queryConfig = config.get("query");
CommentedConfig metricsConfig = config.get("metrics");
- CommentedConfig messagesConfig = config.get("messages");
PlayerInfoForwarding forwardingMode = config.getEnumOrElse("player-info-forwarding-mode",
PlayerInfoForwarding.NONE);
PingPassthroughMode pingPassthroughMode = config.getEnumOrElse("ping-passthrough",
@@ -480,8 +471,7 @@ public class VelocityConfiguration implements ProxyConfig {
new ForcedHosts(forcedHostsConfig),
new Advanced(advancedConfig),
new Query(queryConfig),
- new Metrics(metricsConfig),
- new Messages(messagesConfig, defaultConfig.get("messages"))
+ new Metrics(metricsConfig)
);
}
@@ -793,73 +783,4 @@ public class VelocityConfiguration implements ProxyConfig {
return enabled;
}
}
-
- public static class Messages {
-
- private final CommentedConfig toml;
- private final CommentedConfig defaultToml;
-
- private final String kickPrefix;
- private final String disconnectPrefix;
- private final String onlineModeOnly;
- private final String noAvailableServers;
- private final String alreadyConnected;
- private final String movedToNewServerPrefix;
- private final String genericConnectionError;
-
- private Messages(CommentedConfig toml, CommentedConfig defaultToml) {
- this.toml = toml;
- this.defaultToml = defaultToml;
- this.kickPrefix = getString("kick-prefix");
- this.disconnectPrefix = getString("disconnect-prefix");
- this.onlineModeOnly = getString("online-mode-only");
- this.noAvailableServers = getString("no-available-servers");
- this.alreadyConnected = getString("already-connected");
- this.movedToNewServerPrefix = getString("moved-to-new-server-prefix");
- this.genericConnectionError = getString("generic-connection-error");
- }
-
- private String getString(String path) {
- String def = defaultToml.getOrElse(path, "");
- if (toml == null) {
- return def;
- }
- return toml.getOrElse(path, def);
- }
-
- public Component getKickPrefix(String server) {
- return deserialize(String.format(kickPrefix, server));
- }
-
- public Component getDisconnectPrefix(String server) {
- return deserialize(String.format(disconnectPrefix, server));
- }
-
- public Component getOnlineModeOnly() {
- return deserialize(onlineModeOnly);
- }
-
- public Component getNoAvailableServers() {
- return deserialize(noAvailableServers);
- }
-
- public Component getAlreadyConnected() {
- return deserialize(alreadyConnected);
- }
-
- public Component getMovedToNewServerPrefix() {
- return deserialize(movedToNewServerPrefix);
- }
-
- public Component getGenericConnectionError() {
- return deserialize(genericConnectionError);
- }
-
- private Component deserialize(String str) {
- if (str.startsWith("{")) {
- return GsonComponentSerializer.gson().deserialize(str);
- }
- return LegacyComponentSerializer.legacyAmpersand().deserialize(str);
- }
- }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java
index 6cdac9475..a06fa6600 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java
@@ -50,8 +50,8 @@ import net.kyori.adventure.text.TextComponent;
public class LoginSessionHandler implements MinecraftSessionHandler {
- private static final TextComponent MODERN_IP_FORWARDING_FAILURE = Component
- .text("Your server did not send a forwarding request to the proxy. Is it set up correctly?");
+ private static final Component MODERN_IP_FORWARDING_FAILURE = Component
+ .translatable("velocity.error.modern-forwarding-failed");
private final VelocityServer server;
private final VelocityServerConnection serverConn;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
index ae6e48d1a..3840f0b3c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
@@ -168,9 +168,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
.exceptionally(e -> {
logger.info("Exception occurred while running command for {}",
player.username(), e);
- player.sendMessage(Identity.nil(),
- Component.text("An error occurred while running this command.",
- NamedTextColor.RED));
+ player.sendMessage(Component.translatable("velocity.command.generic-error",
+ NamedTextColor.RED));
return null;
});
} else {
@@ -335,7 +334,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
@Override
public void exception(Throwable throwable) {
- player.disconnect(server.configuration().getMessages().getGenericConnectionError());
+ player.disconnect(Component.translatable("velocity.error.player-connection-error",
+ NamedTextColor.RED));
}
@Override
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java
index 8de648b6a..5e432c164 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java
@@ -446,18 +446,18 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
wrapped = cause;
}
}
- String userMessage;
+
+ Component friendlyError;
if (connectedServer != null && connectedServer.serverInfo().equals(server.serverInfo())) {
- userMessage = "Your connection to " + server.serverInfo().name() + " encountered an "
- + "error.";
+ friendlyError = Component.translatable("velocity.error.connected-server-error",
+ Component.text(server.serverInfo().name()));
} else {
logger.error("{}: unable to connect to server {}", this, server.serverInfo().name(),
wrapped);
- userMessage = "Unable to connect to " + server.serverInfo().name() + ". Try again "
- + "later.";
+ friendlyError = Component.translatable("velocity.error.connecting-server-error",
+ Component.text(server.serverInfo().name()));
}
- handleConnectionException(server, null, Component.text(userMessage,
- NamedTextColor.RED), safe);
+ handleConnectionException(server, null, friendlyError.color(NamedTextColor.RED), safe);
}
/**
@@ -473,26 +473,22 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
return;
}
- VelocityConfiguration.Messages messages = this.server.configuration().getMessages();
Component disconnectReason = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
String plainTextReason = PASS_THRU_TRANSLATE.serialize(disconnectReason);
if (connectedServer != null && connectedServer.serverInfo().equals(server.serverInfo())) {
logger.error("{}: kicked from server {}: {}", this, server.serverInfo().name(),
plainTextReason);
- handleConnectionException(server, disconnectReason, Component.text()
- .append(messages.getKickPrefix(server.serverInfo().name())
- .colorIfAbsent(NamedTextColor.RED))
- .color(NamedTextColor.RED)
- .append(disconnectReason)
- .build(), safe);
+ handleConnectionException(server, disconnectReason,
+ Component.translatable("velocity.error.moved-to-new-server", NamedTextColor.RED,
+ Component.text(server.serverInfo().name()),
+ disconnectReason), safe);
} else {
logger.error("{}: disconnected while connecting to {}: {}", this,
server.serverInfo().name(), plainTextReason);
- handleConnectionException(server, disconnectReason, Component.text()
- .append(messages.getDisconnectPrefix(server.serverInfo().name())
- .colorIfAbsent(NamedTextColor.RED))
- .append(disconnectReason)
- .build(), safe);
+ handleConnectionException(server, disconnectReason,
+ Component.translatable("velocity.error.cant-connect", NamedTextColor.RED,
+ Component.text(server.serverInfo().name()),
+ disconnectReason), safe);
}
}
@@ -576,8 +572,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
protocolVersion()), ((Impl) status).isSafe());
break;
case SUCCESS:
- sendMessage(Identity.nil(), server.configuration().getMessages()
- .getMovedToNewServerPrefix().append(friendlyReason));
+ sendMessage(Component.translatable("velocity.error.moved-to-new-server",
+ NamedTextColor.RED,
+ Component.text(originalEvent.server().serverInfo().name()),
+ friendlyReason));
break;
default:
// The only remaining value is successful (no need to do anything!)
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java
index bfe109eaf..8d9fbf669 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java
@@ -70,7 +70,10 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
@Override
public boolean handle(LegacyHandshakePacket packet) {
connection.closeWith(LegacyDisconnectPacket
- .from(Component.text("Your client is old, please upgrade!", NamedTextColor.RED)));
+ .from(Component.text(
+ "Your client is extremely old. Please update to a newer version of Minecraft.",
+ NamedTextColor.RED)
+ ));
return true;
}
@@ -122,7 +125,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress();
if (!server.getIpAttemptLimiter().attempt(address)) {
- ic.disconnectQuietly(Component.text("You are logging in too fast, try again later."));
+ ic.disconnectQuietly(Component.translatable("velocity.error.logging-in-too-fast"));
return;
}
@@ -132,7 +135,8 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
// and lower, otherwise IP information will never get forwarded.
if (server.configuration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
&& handshake.getProtocolVersion().lt(ProtocolVersion.MINECRAFT_1_13)) {
- ic.disconnectQuietly(Component.text("This server is only compatible with 1.13 and above."));
+ ic.disconnectQuietly(Component.translatable(
+ "velocity.error.modern-forwarding-needs-new-client"));
return;
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java
index 008644ff3..4acde610d 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/LoginSessionHandler.java
@@ -65,6 +65,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.translation.GlobalTranslator;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -152,7 +153,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
GameProfile.class), true);
} else if (profileResponse.getStatusCode() == 204) {
// Apparently an offline-mode user logged onto this online-mode proxy.
- inbound.disconnect(server.configuration().getMessages().getOnlineModeOnly());
+ inbound.disconnect(Component.translatable("velocity.error.online-mode-only",
+ NamedTextColor.RED));
} else {
// Something else went wrong
logger.error(
@@ -192,9 +194,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
Optional disconnectReason = result.denialReason();
if (disconnectReason.isPresent()) {
// The component is guaranteed to be provided if the connection was denied.
- Component disconnectReasonTranslated = GlobalTranslator.render(disconnectReason.get(),
- Locale.getDefault());
- inbound.disconnect(disconnectReasonTranslated);
+ inbound.disconnect(disconnectReason.get());
return;
}
@@ -243,7 +243,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
mcConnection, inbound.connectedHost().orElse(null), onlineMode);
this.connectedPlayer = player;
if (!server.canRegisterConnection(player)) {
- player.disconnect0(server.configuration().getMessages().getAlreadyConnected(), true);
+ player.disconnect0(Component.translatable("velocity.error.already-connected-proxy",
+ NamedTextColor.RED), true);
return CompletableFuture.completedFuture(null);
}
@@ -304,8 +305,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
player.disconnect0(reason.get(), true);
} else {
if (!server.registerConnection(player)) {
- player.disconnect0(server.configuration().getMessages()
- .getAlreadyConnected(), true);
+ player.disconnect0(Component.translatable("velocity.error.already-connected-proxy"),
+ true);
return;
}
@@ -333,8 +334,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
.thenRunAsync(() -> {
Optional toTry = event.initialServer();
if (!toTry.isPresent()) {
- player.disconnect0(server.configuration().getMessages()
- .getNoAvailableServers(), true);
+ player.disconnect0(Component.translatable("velocity.error.no-available-servers",
+ NamedTextColor.RED), true);
return;
}
player.createConnectionRequest(toTry.get()).fireAndForget();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionMessages.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionMessages.java
index bbb6c2daf..5e29672ce 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionMessages.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/util/ConnectionMessages.java
@@ -19,16 +19,17 @@ package com.velocitypowered.proxy.connection.util;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
+import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.format.NamedTextColor;
public class ConnectionMessages {
- public static final TextComponent ALREADY_CONNECTED = Component
- .text("You are already connected to this server!", NamedTextColor.RED);
- public static final TextComponent IN_PROGRESS = Component
- .text("You are already connecting to a server!", NamedTextColor.RED);
- public static final TextComponent INTERNAL_SERVER_CONNECTION_ERROR = Component
- .text("An internal server connection error occurred.", NamedTextColor.RED);
+ public static final TranslatableComponent ALREADY_CONNECTED = Component
+ .translatable("velocity.error.already-connected", NamedTextColor.RED);
+ public static final TranslatableComponent IN_PROGRESS = Component
+ .translatable("velocity.error.already-connecting", NamedTextColor.RED);
+ public static final TranslatableComponent INTERNAL_SERVER_CONNECTION_ERROR = Component
+ .translatable("velocity.error.internal-server-connection-error", NamedTextColor.RED);
private ConnectionMessages() {
throw new AssertionError();
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/console/VelocityConsole.java b/proxy/src/main/java/com/velocitypowered/proxy/console/VelocityConsole.java
index 80e4e3ea6..d3138a60e 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/console/VelocityConsole.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/console/VelocityConsole.java
@@ -26,9 +26,12 @@ import com.velocitypowered.api.permission.PermissionFunction;
import com.velocitypowered.api.permission.Tristate;
import com.velocitypowered.proxy.VelocityServer;
import java.util.List;
+import java.util.Locale;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
+import net.kyori.adventure.translation.GlobalTranslator;
import net.minecrell.terminalconsole.SimpleTerminalConsole;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
@@ -52,8 +55,8 @@ public final class VelocityConsole extends SimpleTerminalConsole implements Cons
@Override
public void sendMessage(@NonNull Identity identity, @NonNull Component message) {
- logger.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection()
- .serialize(message));
+ Component translated = GlobalTranslator.render(message, Locale.getDefault());
+ logger.info(LegacyComponentSerializer.legacySection().serialize(translated));
}
@Override
@@ -114,7 +117,8 @@ public final class VelocityConsole extends SimpleTerminalConsole implements Cons
protected void runCommand(String command) {
try {
if (!this.server.commandManager().execute(this, command).join()) {
- sendMessage(Component.text("Command not found.", NamedTextColor.RED));
+ sendMessage(Component.translatable("velocity.command.command-does-not-exist",
+ NamedTextColor.RED));
}
} catch (Exception e) {
logger.error("An error occurred while running this command.", e);
diff --git a/proxy/src/main/resources/com/velocitypowered/proxy/messages.properties b/proxy/src/main/resources/com/velocitypowered/proxy/messages.properties
new file mode 100644
index 000000000..df291dc77
--- /dev/null
+++ b/proxy/src/main/resources/com/velocitypowered/proxy/messages.properties
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2018 Velocity Contributors
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+
+velocity.error.already-connected=You are already connected to this server!
+velocity.error.already-connected-proxy=You are already connected to this proxy!
+velocity.error.already-connecting=You are already trying to connect to a server!
+velocity.error.cant-connect=Unable to connect to {0}: {1}
+velocity.error.connecting-server-error=Unable to connect you to {0}. Please try again later.
+velocity.error.connected-server-error=Your connection to {0} encountered a problem.
+velocity.error.internal-server-connection-error=An internal server connection error occurred.
+velocity.error.logging-in-too-fast=You are logging in too fast, try again later.
+velocity.error.online-mode-only=You are not logged into your Minecraft account. If you are logged into your Minecraft account, try restarting your Minecraft client.
+velocity.error.player-connection-error=An internal error occurred in your connection.
+velocity.error.modern-forwarding-needs-new-client=This server is only compatible with Minecraft 1.13 and above.
+velocity.error.modern-forwarding-failed=Your server did not send a forwarding request to the proxy. Make sure the server is configured for Velocity forwarding.
+velocity.error.moved-to-new-server=YOu were kicked from {0}: {1}
+velocity.error.no-available-servers=There are no available servers to connect you to. Try again later or contact an admin.
+
+# Commands
+velocity.command.generic-error=An error occurred while running this command.
+velocity.command.command-does-not-exist=This command does not exist.
+
+velocity.command.players-only=Only players can run this command.
+velocity.command.server-does-not-exist=The specified server {0} does not exist.
+
+velocity.command.server-current-server=You are currently connected to {0}.
+velocity.command.server-too-many=There are too many servers set up. Use tab completion to get individual server counts.
+velocity.command.server-available=Available servers:
+velocity.command.server-tooltip-player-online={0} player online
+velocity.command.server-tooltip-players-online={0} players online
+velocity.command.server-tooltip-current-server=Currently connected to this server
+velocity.command.server-tooltip-offer-connect-server=Click to connect to this server
+
+velocity.command.glist-player-singular=player
+velocity.command.glist-player-plural=players
+velocity.command.glist-total-suffix= are currently connected to the proxy.
+velocity.command.glist-view-all=To view all players on servers, use /glist all.
+
+velocity.command.reload-success=Velocity configuration successfully reloaded.
+velocity.command.reload-failure=Unable to reload your Velocity configuration. Check the console for more details.
+
+velocity.command.version-copyright=Copyright 2018-2021 {0}. {1} is licensed under the terms of the GNU General Public License v3.
+
+velocity.command.no-plugins=There are no plugins currently installed.
+velocity.command.plugins-list=Plugins: {0}
+velocity.command.plugin-tooltip-website=Website: {0}
+velocity.command.plugin-tooltip-author=Author: {0}
+velocity.command.plugin-tooltip-authors=Authors: {0}
\ No newline at end of file
diff --git a/proxy/src/main/resources/default-velocity.toml b/proxy/src/main/resources/default-velocity.toml
index fbad6626c..4a8447336 100644
--- a/proxy/src/main/resources/default-velocity.toml
+++ b/proxy/src/main/resources/default-velocity.toml
@@ -141,20 +141,4 @@ port = 25577
map = "Velocity"
# Whether plugins should be shown in query response by default or not
-show-plugins = false
-
-# Legacy color codes and JSON are accepted in all messages.
-[messages]
-# Prefix when the player gets kicked from a server.
-# First argument '%s': the server name
-kick-prefix = "&cKicked from %s: "
-
-# Prefix when the player is disconnected from a server.
-# First argument '%s': the server name
-disconnect-prefix = "&cCan't connect to %s: "
-
-online-mode-only = "&cThis server only accepts connections from online-mode clients.\n\n&7Did you change your username? Sign out of Minecraft, sign back in, and try again."
-no-available-servers = "&cThere are no available servers."
-already-connected = "&cYou are already connected to this proxy!"
-moved-to-new-server-prefix = "&cThe server you were on kicked you: "
-generic-connection-error = "&cAn internal error occurred in your connection."
+show-plugins = false
\ No newline at end of file