3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-17 05:20:14 +01:00

Merge pull request #356 from FrankHeijden/feature/messages

Make hardcoded messages configurable
Dieser Commit ist enthalten in:
Andrew Steinborn 2020-08-20 23:16:11 -04:00 committet von GitHub
Commit c15a49ce7d
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
6 geänderte Dateien mit 126 neuen und 44 gelöschten Zeilen

Datei anzeigen

@ -3,25 +3,32 @@ package com.velocitypowered.proxy.config;
import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.toml.TomlFormat;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.velocitypowered.api.proxy.config.ProxyConfig; import com.velocitypowered.api.proxy.config.ProxyConfig;
import com.velocitypowered.api.util.Favicon; import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.proxy.util.AddressUtil; import com.velocitypowered.proxy.util.AddressUtil;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.legacytext3.LegacyText3ComponentSerializer; import net.kyori.adventure.text.serializer.legacytext3.LegacyText3ComponentSerializer;
@ -49,22 +56,24 @@ public class VelocityConfiguration implements ProxyConfig {
private final Advanced advanced; private final Advanced advanced;
private final Query query; private final Query query;
private final Metrics metrics; private final Metrics metrics;
private final Messages messages;
private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent; private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent;
private @Nullable Favicon favicon; private @Nullable Favicon favicon;
private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced, private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced,
Query query, Metrics metrics) { Query query, Metrics metrics, Messages messages) {
this.servers = servers; this.servers = servers;
this.forcedHosts = forcedHosts; this.forcedHosts = forcedHosts;
this.advanced = advanced; this.advanced = advanced;
this.query = query; this.query = query;
this.metrics = metrics; this.metrics = metrics;
this.messages = messages;
} }
private VelocityConfiguration(String bind, String motd, int showMaxPlayers, boolean onlineMode, private VelocityConfiguration(String bind, String motd, int showMaxPlayers, boolean onlineMode,
boolean announceForge, PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret, boolean announceForge, PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret,
boolean onlineModeKickExistingPlayers, PingPassthroughMode pingPassthrough, Servers servers, boolean onlineModeKickExistingPlayers, PingPassthroughMode pingPassthrough, Servers servers,
ForcedHosts forcedHosts, Advanced advanced, Query query, Metrics metrics) { ForcedHosts forcedHosts, Advanced advanced, Query query, Metrics metrics, Messages messages) {
this.bind = bind; this.bind = bind;
this.motd = motd; this.motd = motd;
this.showMaxPlayers = showMaxPlayers; this.showMaxPlayers = showMaxPlayers;
@ -79,6 +88,7 @@ public class VelocityConfiguration implements ProxyConfig {
this.advanced = advanced; this.advanced = advanced;
this.query = query; this.query = query;
this.metrics = metrics; this.metrics = metrics;
this.messages = messages;
} }
/** /**
@ -359,6 +369,10 @@ public class VelocityConfiguration implements ProxyConfig {
return advanced.isLogCommandExecutions(); return advanced.isLogCommandExecutions();
} }
public Messages getMessages() {
return messages;
}
@Override @Override
public String toString() { public String toString() {
return MoreObjects.toStringHelper(this) return MoreObjects.toStringHelper(this)
@ -384,15 +398,28 @@ public class VelocityConfiguration implements ProxyConfig {
* @throws IOException if we could not read from the {@code path}. * @throws IOException if we could not read from the {@code path}.
*/ */
public static VelocityConfiguration read(Path path) throws IOException { public static VelocityConfiguration read(Path path) throws IOException {
String defaultResource = "default-velocity.toml";
boolean mustResave = false; boolean mustResave = false;
CommentedFileConfig config = CommentedFileConfig.builder(path) CommentedFileConfig config = CommentedFileConfig.builder(path)
.defaultResource("/default-velocity.toml") .defaultResource(defaultResource)
.autosave() .autosave()
.preserveInsertionOrder() .preserveInsertionOrder()
.sync() .sync()
.build(); .build();
config.load(); config.load();
// Create temporary default configuration
File tmpFile = File.createTempFile(defaultResource, null);
tmpFile.deleteOnExit();
// Copy over default file to tmp location
ClassLoader loader = VelocityConfiguration.class.getClassLoader();
try (InputStream in = loader.getResourceAsStream(defaultResource)) {
Files.copy(Objects.requireNonNull(in), tmpFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
CommentedFileConfig defaultConfig = CommentedFileConfig.of(tmpFile, TomlFormat.instance());
defaultConfig.load();
// Handle any cases where the config needs to be saved again // Handle any cases where the config needs to be saved again
byte[] forwardingSecret; byte[] forwardingSecret;
String forwardingSecretString = config.get("forwarding-secret"); String forwardingSecretString = config.get("forwarding-secret");
@ -418,6 +445,7 @@ public class VelocityConfiguration implements ProxyConfig {
CommentedConfig advancedConfig = config.get("advanced"); CommentedConfig advancedConfig = config.get("advanced");
CommentedConfig queryConfig = config.get("query"); CommentedConfig queryConfig = config.get("query");
CommentedConfig metricsConfig = config.get("metrics"); CommentedConfig metricsConfig = config.get("metrics");
CommentedConfig messagesConfig = config.get("messages");
PlayerInfoForwarding forwardingMode = config.getEnumOrElse("player-info-forwarding-mode", PlayerInfoForwarding forwardingMode = config.getEnumOrElse("player-info-forwarding-mode",
PlayerInfoForwarding.NONE); PlayerInfoForwarding.NONE);
PingPassthroughMode pingPassthroughMode = config.getEnumOrElse("ping-passthrough", PingPassthroughMode pingPassthroughMode = config.getEnumOrElse("ping-passthrough",
@ -444,7 +472,8 @@ public class VelocityConfiguration implements ProxyConfig {
new ForcedHosts(forcedHostsConfig), new ForcedHosts(forcedHostsConfig),
new Advanced(advancedConfig), new Advanced(advancedConfig),
new Query(queryConfig), new Query(queryConfig),
new Metrics(metricsConfig) new Metrics(metricsConfig),
new Messages(messagesConfig, defaultConfig.get("messages"))
); );
} }
@ -781,4 +810,69 @@ public class VelocityConfiguration implements ProxyConfig {
return fromConfig; return fromConfig;
} }
} }
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) {
return toml.getOrElse(path, defaultToml.getOrElse(path, ""));
}
public Component getKickPrefix(String server) {
return serialize(String.format(kickPrefix, server));
}
public Component getDisconnectPrefix(String server) {
return serialize(String.format(disconnectPrefix, server));
}
public Component getOnlineModeOnly() {
return serialize(onlineModeOnly);
}
public Component getNoAvailableServers() {
return serialize(noAvailableServers);
}
public Component getAlreadyConnected() {
return serialize(alreadyConnected);
}
public Component getMovedToNewServerPrefix() {
return serialize(movedToNewServerPrefix);
}
public Component getGenericConnectionError() {
return serialize(genericConnectionError);
}
private Component serialize(String str) {
if (str.startsWith("{")) {
return GsonComponentSerializer.gson().deserialize(str);
}
return LegacyComponentSerializer.legacyAmpersand().deserialize(str);
}
}
} }

Datei anzeigen

@ -31,7 +31,6 @@ import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse.Offer; import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse.Offer;
import com.velocitypowered.proxy.protocol.packet.TitlePacket; import com.velocitypowered.proxy.protocol.packet.TitlePacket;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil; import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import com.velocitypowered.proxy.util.VelocityMessages;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@ -279,7 +278,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
@Override @Override
public void exception(Throwable throwable) { public void exception(Throwable throwable) {
player.disconnect(VelocityMessages.GENERIC_CONNECTION_ERROR); player.disconnect(server.getConfiguration().getMessages().getGenericConnectionError());
} }
@Override @Override

Datei anzeigen

@ -32,6 +32,7 @@ import com.velocitypowered.api.util.title.TextTitle;
import com.velocitypowered.api.util.title.Title; import com.velocitypowered.api.util.title.Title;
import com.velocitypowered.api.util.title.Titles; import com.velocitypowered.api.util.title.Titles;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.config.VelocityConfiguration;
import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation; import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection; import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
@ -52,7 +53,6 @@ import com.velocitypowered.proxy.server.VelocityRegisteredServer;
import com.velocitypowered.proxy.tablist.VelocityTabList; import com.velocitypowered.proxy.tablist.VelocityTabList;
import com.velocitypowered.proxy.tablist.VelocityTabListLegacy; import com.velocitypowered.proxy.tablist.VelocityTabListLegacy;
import com.velocitypowered.proxy.util.DurationUtils; import com.velocitypowered.proxy.util.DurationUtils;
import com.velocitypowered.proxy.util.VelocityMessages;
import com.velocitypowered.proxy.util.collect.CappedSet; import com.velocitypowered.proxy.util.collect.CappedSet;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@ -520,13 +520,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
return; return;
} }
VelocityConfiguration.Messages messages = this.server.getConfiguration().getMessages();
Component disconnectReason = GsonComponentSerializer.gson().deserialize(disconnect.getReason()); Component disconnectReason = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
String plainTextReason = PASS_THRU_TRANSLATE.serialize(disconnectReason); String plainTextReason = PASS_THRU_TRANSLATE.serialize(disconnectReason);
if (connectedServer != null && connectedServer.getServerInfo().equals(server.getServerInfo())) { if (connectedServer != null && connectedServer.getServerInfo().equals(server.getServerInfo())) {
logger.error("{}: kicked from server {}: {}", this, server.getServerInfo().getName(), logger.error("{}: kicked from server {}: {}", this, server.getServerInfo().getName(),
plainTextReason); plainTextReason);
handleConnectionException(server, disconnectReason, TextComponent.builder() handleConnectionException(server, disconnectReason, TextComponent.builder()
.content("Kicked from " + server.getServerInfo().getName() + ": ") .append(messages.getKickPrefix(server.getServerInfo().getName()))
.color(NamedTextColor.RED) .color(NamedTextColor.RED)
.append(disconnectReason) .append(disconnectReason)
.build(), safe); .build(), safe);
@ -534,7 +535,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
logger.error("{}: disconnected while connecting to {}: {}", this, logger.error("{}: disconnected while connecting to {}: {}", this,
server.getServerInfo().getName(), plainTextReason); server.getServerInfo().getName(), plainTextReason);
handleConnectionException(server, disconnectReason, TextComponent.builder() handleConnectionException(server, disconnectReason, TextComponent.builder()
.content("Can't connect to server " + server.getServerInfo().getName() + ": ") .append(messages.getDisconnectPrefix(server.getServerInfo().getName()))
.color(NamedTextColor.RED) .color(NamedTextColor.RED)
.append(disconnectReason) .append(disconnectReason)
.build(), safe); .build(), safe);
@ -597,7 +598,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
disconnect(friendlyReason); disconnect(friendlyReason);
} else { } else {
if (res.getMessageComponent() == null) { if (res.getMessageComponent() == null) {
sendMessage(VelocityMessages.MOVED_TO_NEW_SERVER.append(friendlyReason)); sendMessage(server.getConfiguration().getMessages()
.getMovedToNewServerPrefix().append(friendlyReason));
} else { } else {
sendMessage(res.getMessageComponent()); sendMessage(res.getMessageComponent());
} }

Datei anzeigen

@ -33,7 +33,6 @@ import com.velocitypowered.proxy.protocol.packet.EncryptionResponse;
import com.velocitypowered.proxy.protocol.packet.ServerLogin; import com.velocitypowered.proxy.protocol.packet.ServerLogin;
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess; import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
import com.velocitypowered.proxy.protocol.packet.SetCompression; import com.velocitypowered.proxy.protocol.packet.SetCompression;
import com.velocitypowered.proxy.util.VelocityMessages;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.ReadTimeoutHandler;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -133,7 +132,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
GameProfile.class), true); GameProfile.class), true);
} else if (profileResponse.getStatusCode() == 204) { } else if (profileResponse.getStatusCode() == 204) {
// Apparently an offline-mode user logged onto this online-mode proxy. // Apparently an offline-mode user logged onto this online-mode proxy.
inbound.disconnect(VelocityMessages.ONLINE_MODE_ONLY); inbound.disconnect(server.getConfiguration().getMessages().getOnlineModeOnly());
} else { } else {
// Something else went wrong // Something else went wrong
logger.error( logger.error(
@ -224,7 +223,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
mcConnection, inbound.getVirtualHost().orElse(null), onlineMode); mcConnection, inbound.getVirtualHost().orElse(null), onlineMode);
this.connectedPlayer = player; this.connectedPlayer = player;
if (!server.canRegisterConnection(player)) { if (!server.canRegisterConnection(player)) {
player.disconnect0(VelocityMessages.ALREADY_CONNECTED, true); player.disconnect0(server.getConfiguration().getMessages().getAlreadyConnected(), true);
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
@ -275,7 +274,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
player.disconnect0(reason.get(), true); player.disconnect0(reason.get(), true);
} else { } else {
if (!server.registerConnection(player)) { if (!server.registerConnection(player)) {
player.disconnect0(VelocityMessages.ALREADY_CONNECTED, true); player.disconnect0(server.getConfiguration().getMessages()
.getAlreadyConnected(), true);
return; return;
} }
@ -295,7 +295,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
.thenRunAsync(() -> { .thenRunAsync(() -> {
Optional<RegisteredServer> toTry = event.getInitialServer(); Optional<RegisteredServer> toTry = event.getInitialServer();
if (!toTry.isPresent()) { if (!toTry.isPresent()) {
player.disconnect0(VelocityMessages.NO_AVAILABLE_SERVERS, true); player.disconnect0(server.getConfiguration().getMessages()
.getNoAvailableServers(), true);
return; return;
} }
player.createConnectionRequest(toTry.get()).fireAndForget(); player.createConnectionRequest(toTry.get()).fireAndForget();

Datei anzeigen

@ -1,29 +0,0 @@
package com.velocitypowered.proxy.util;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
public final class VelocityMessages {
public static final Component ONLINE_MODE_ONLY = TextComponent
.builder("This server only accepts connections from online-mode clients.")
.color(NamedTextColor.RED)
.append(
TextComponent.of("\n\nDid you change your username? Sign out of Minecraft, sign back in, "
+ "and try again.", NamedTextColor.GRAY)
)
.build();
public static final Component NO_AVAILABLE_SERVERS = TextComponent
.of("There are no available servers.", NamedTextColor.RED);
public static final Component ALREADY_CONNECTED = TextComponent
.of("You are already connected to this proxy!", NamedTextColor.RED);
public static final Component MOVED_TO_NEW_SERVER = TextComponent
.of("The server you were on kicked you: ", NamedTextColor.RED);
public static final Component GENERIC_CONNECTION_ERROR = TextComponent
.of("An internal error occurred in your connection.", NamedTextColor.RED);
private VelocityMessages() {
throw new AssertionError();
}
}

Datei anzeigen

@ -158,3 +158,18 @@ id = ""
log-failure = false log-failure = 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."