Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-24 15:20:35 +01:00
Merge pull request #356 from FrankHeijden/feature/messages
Make hardcoded messages configurable
Dieser Commit ist enthalten in:
Commit
c15a49ce7d
@ -3,25 +3,32 @@ package com.velocitypowered.proxy.config;
|
||||
import com.electronwill.nightconfig.core.CommentedConfig;
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
|
||||
import com.electronwill.nightconfig.toml.TomlFormat;
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.velocitypowered.api.proxy.config.ProxyConfig;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
import com.velocitypowered.proxy.util.AddressUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacytext3.LegacyText3ComponentSerializer;
|
||||
@ -49,22 +56,24 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
private final Advanced advanced;
|
||||
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) {
|
||||
Query query, Metrics metrics, Messages messages) {
|
||||
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 announceForge, PlayerInfoForwarding playerInfoForwardingMode, byte[] forwardingSecret,
|
||||
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.motd = motd;
|
||||
this.showMaxPlayers = showMaxPlayers;
|
||||
@ -79,6 +88,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
this.advanced = advanced;
|
||||
this.query = query;
|
||||
this.metrics = metrics;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,6 +369,10 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
return advanced.isLogCommandExecutions();
|
||||
}
|
||||
|
||||
public Messages getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
@ -384,15 +398,28 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
* @throws IOException if we could not read from the {@code path}.
|
||||
*/
|
||||
public static VelocityConfiguration read(Path path) throws IOException {
|
||||
String defaultResource = "default-velocity.toml";
|
||||
boolean mustResave = false;
|
||||
CommentedFileConfig config = CommentedFileConfig.builder(path)
|
||||
.defaultResource("/default-velocity.toml")
|
||||
.defaultResource(defaultResource)
|
||||
.autosave()
|
||||
.preserveInsertionOrder()
|
||||
.sync()
|
||||
.build();
|
||||
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
|
||||
byte[] forwardingSecret;
|
||||
String forwardingSecretString = config.get("forwarding-secret");
|
||||
@ -418,6 +445,7 @@ 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",
|
||||
@ -444,7 +472,8 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
new ForcedHosts(forcedHostsConfig),
|
||||
new Advanced(advancedConfig),
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.TitlePacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import com.velocitypowered.proxy.util.VelocityMessages;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@ -279,7 +278,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
@Override
|
||||
public void exception(Throwable throwable) {
|
||||
player.disconnect(VelocityMessages.GENERIC_CONNECTION_ERROR);
|
||||
player.disconnect(server.getConfiguration().getMessages().getGenericConnectionError());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +32,7 @@ import com.velocitypowered.api.util.title.TextTitle;
|
||||
import com.velocitypowered.api.util.title.Title;
|
||||
import com.velocitypowered.api.util.title.Titles;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.config.VelocityConfiguration;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
|
||||
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.VelocityTabListLegacy;
|
||||
import com.velocitypowered.proxy.util.DurationUtils;
|
||||
import com.velocitypowered.proxy.util.VelocityMessages;
|
||||
import com.velocitypowered.proxy.util.collect.CappedSet;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@ -520,13 +520,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
return;
|
||||
}
|
||||
|
||||
VelocityConfiguration.Messages messages = this.server.getConfiguration().getMessages();
|
||||
Component disconnectReason = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
|
||||
String plainTextReason = PASS_THRU_TRANSLATE.serialize(disconnectReason);
|
||||
if (connectedServer != null && connectedServer.getServerInfo().equals(server.getServerInfo())) {
|
||||
logger.error("{}: kicked from server {}: {}", this, server.getServerInfo().getName(),
|
||||
plainTextReason);
|
||||
handleConnectionException(server, disconnectReason, TextComponent.builder()
|
||||
.content("Kicked from " + server.getServerInfo().getName() + ": ")
|
||||
.append(messages.getKickPrefix(server.getServerInfo().getName()))
|
||||
.color(NamedTextColor.RED)
|
||||
.append(disconnectReason)
|
||||
.build(), safe);
|
||||
@ -534,7 +535,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
logger.error("{}: disconnected while connecting to {}: {}", this,
|
||||
server.getServerInfo().getName(), plainTextReason);
|
||||
handleConnectionException(server, disconnectReason, TextComponent.builder()
|
||||
.content("Can't connect to server " + server.getServerInfo().getName() + ": ")
|
||||
.append(messages.getDisconnectPrefix(server.getServerInfo().getName()))
|
||||
.color(NamedTextColor.RED)
|
||||
.append(disconnectReason)
|
||||
.build(), safe);
|
||||
@ -597,7 +598,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||
disconnect(friendlyReason);
|
||||
} else {
|
||||
if (res.getMessageComponent() == null) {
|
||||
sendMessage(VelocityMessages.MOVED_TO_NEW_SERVER.append(friendlyReason));
|
||||
sendMessage(server.getConfiguration().getMessages()
|
||||
.getMovedToNewServerPrefix().append(friendlyReason));
|
||||
} else {
|
||||
sendMessage(res.getMessageComponent());
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ import com.velocitypowered.proxy.protocol.packet.EncryptionResponse;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLogin;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccess;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompression;
|
||||
import com.velocitypowered.proxy.util.VelocityMessages;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||
import java.net.InetSocketAddress;
|
||||
@ -133,7 +132,7 @@ 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(VelocityMessages.ONLINE_MODE_ONLY);
|
||||
inbound.disconnect(server.getConfiguration().getMessages().getOnlineModeOnly());
|
||||
} else {
|
||||
// Something else went wrong
|
||||
logger.error(
|
||||
@ -224,7 +223,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
mcConnection, inbound.getVirtualHost().orElse(null), onlineMode);
|
||||
this.connectedPlayer = player;
|
||||
if (!server.canRegisterConnection(player)) {
|
||||
player.disconnect0(VelocityMessages.ALREADY_CONNECTED, true);
|
||||
player.disconnect0(server.getConfiguration().getMessages().getAlreadyConnected(), true);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@ -275,7 +274,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
player.disconnect0(reason.get(), true);
|
||||
} else {
|
||||
if (!server.registerConnection(player)) {
|
||||
player.disconnect0(VelocityMessages.ALREADY_CONNECTED, true);
|
||||
player.disconnect0(server.getConfiguration().getMessages()
|
||||
.getAlreadyConnected(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -295,7 +295,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
.thenRunAsync(() -> {
|
||||
Optional<RegisteredServer> toTry = event.getInitialServer();
|
||||
if (!toTry.isPresent()) {
|
||||
player.disconnect0(VelocityMessages.NO_AVAILABLE_SERVERS, true);
|
||||
player.disconnect0(server.getConfiguration().getMessages()
|
||||
.getNoAvailableServers(), true);
|
||||
return;
|
||||
}
|
||||
player.createConnectionRequest(toTry.get()).fireAndForget();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -158,3 +158,18 @@ id = ""
|
||||
|
||||
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."
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren