diff --git a/patches/api/Make-the-default-permission-message-configurable.patch b/patches/api/Make-the-default-permission-message-configurable.patch index 511e252c8b..0e5d0f0eb1 100644 --- a/patches/api/Make-the-default-permission-message-configurable.patch +++ b/patches/api/Make-the-default-permission-message-configurable.patch @@ -33,11 +33,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 boolean suggestPlayerNamesWhenNullTabCompletions(); + /** ++ * Gets the default no permission message used on the server + * -+ * @return the default no permission message used on the server ++ * @return the default message ++ * @deprecated use {@link #permissionMessage()} + */ + @NotNull ++ @Deprecated + String getPermissionMessage(); ++ ++ /** ++ * Gets the default no permission message used on the server ++ * ++ * @return the default message ++ */ ++ @NotNull net.kyori.adventure.text.Component permissionMessage(); + /** * Creates a PlayerProfile for the specified uuid, with name as null. diff --git a/patches/server/Add-packet-limiter-config.patch b/patches/server/Add-packet-limiter-config.patch index 0a6b78d2df..0137d608d9 100644 --- a/patches/server/Add-packet-limiter-config.patch +++ b/patches/server/Add-packet-limiter-config.patch @@ -40,8 +40,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + private boolean stopReadingPackets; + private void killForPacketSpam() { -+ this.sendPacket(new ClientboundDisconnectPacket(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.kickMessage, true)[0]), (future) -> { -+ this.disconnect(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.kickMessage, true)[0]); ++ this.sendPacket(new ClientboundDisconnectPacket(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.kickMessage)), (future) -> { ++ this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().packetLimiter.kickMessage)); + }); + this.setReadOnly(); + this.stopReadingPackets = true; diff --git a/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch b/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch index 236ac24837..15f4e634a0 100644 --- a/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch +++ b/patches/server/Allow-specifying-a-custom-authentication-servers-dow.patch @@ -13,10 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 ServerLoginPacketListenerImpl.this.gameProfile = ServerLoginPacketListenerImpl.this.createFakeProfile(gameprofile); ServerLoginPacketListenerImpl.this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT; } else { -+ // Paper start -+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown.isEmpty()) { -+ ServerLoginPacketListenerImpl.this.disconnect(Component.literal(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); -+ } else // Paper end - ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.authservers_down")); +- ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.authservers_down")); ++ ServerLoginPacketListenerImpl.this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); // Paper ServerLoginPacketListenerImpl.LOGGER.error("Couldn't verify username because servers are unavailable"); } + // CraftBukkit start - catch all exceptions diff --git a/patches/server/Configurable-connection-throttle-kick-message.patch b/patches/server/Configurable-connection-throttle-kick-message.patch index 015d3c41f2..b4c4880dfd 100644 --- a/patches/server/Configurable-connection-throttle-kick-message.patch +++ b/patches/server/Configurable-connection-throttle-kick-message.patch @@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) { ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime); - MutableComponent chatmessage = Component.literal("Connection throttled! Please wait before reconnecting."); -+ MutableComponent chatmessage = Component.literal(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message ++ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); this.connection.disconnect(chatmessage); return; diff --git a/patches/server/Fix-hex-colors-not-working-in-some-kick-messages.patch b/patches/server/Fix-hex-colors-not-working-in-some-kick-messages.patch index 1501cf4594..1229f796bc 100644 --- a/patches/server/Fix-hex-colors-not-working-in-some-kick-messages.patch +++ b/patches/server/Fix-hex-colors-not-working-in-some-kick-messages.patch @@ -8,15 +8,6 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketLis index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java -@@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL - synchronized (ServerHandshakePacketListenerImpl.throttleTracker) { - if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) { - ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime); -- MutableComponent chatmessage = Component.literal(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message -+ Component chatmessage = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle, true)[0]; // Paper - Configurable connection throttle kick message // Paper - Fix hex colors not working in some kick messages - this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage)); - this.connection.disconnect(chatmessage); - return; @@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL } // CraftBukkit end diff --git a/patches/server/Make-the-default-permission-message-configurable.patch b/patches/server/Make-the-default-permission-message-configurable.patch index 61a1e43448..4b8badec49 100644 --- a/patches/server/Make-the-default-permission-message-configurable.patch +++ b/patches/server/Make-the-default-permission-message-configurable.patch @@ -27,6 +27,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @Override + public String getPermissionMessage() { ++ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(io.papermc.paper.configuration.GlobalConfiguration.get().messages.noPermission); ++ } ++ ++ @Override ++ public net.kyori.adventure.text.Component permissionMessage() { + return io.papermc.paper.configuration.GlobalConfiguration.get().messages.noPermission; + } + diff --git a/patches/server/Paper-config-files.patch b/patches/server/Paper-config-files.patch index 3504fe5dad..03deb5aed6 100644 --- a/patches/server/Paper-config-files.patch +++ b/patches/server/Paper-config-files.patch @@ -411,10 +411,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +package io.papermc.paper.configuration; + +import co.aikar.timings.MinecraftTimings; -+import co.aikar.timings.TimingsManager; +import com.destroystokyo.paper.io.chunk.ChunkTaskManager; +import io.papermc.paper.configuration.constraint.Constraint; +import io.papermc.paper.configuration.constraint.Constraints; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; +import org.checkerframework.checker.nullness.qual.Nullable; @@ -447,13 +448,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public Kick kick; + + public class Kick extends ConfigurationPart { -+ public String authenticationServersDown = ""; // TODO empty is fallback to translatable msg -+ public String connectionThrottle = "Connection throttled! Please wait before reconnecting."; -+ public String flyingPlayer = "Flying is not enabled on this server"; -+ public String flyingVehicle = "Flying is not enabled on this server"; ++ public Component authenticationServersDown = Component.translatable("multiplayer.disconnect.authservers_down"); ++ public Component connectionThrottle = Component.text("Connection throttled! Please wait before reconnecting."); ++ public Component flyingPlayer = Component.translatable("multiplayer.disconnect.flying"); ++ public Component flyingVehicle = Component.translatable("multiplayer.disconnect.flying"); + } + -+ public String noPermission = "&cI'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error."; ++ public Component noPermission = Component.text("I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.", NamedTextColor.RED); + public boolean useDisplayNameInQuitMessage = false; + } + @@ -613,7 +614,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public PacketLimiter packetLimiter; + + public class PacketLimiter extends ConfigurationPart { -+ public String kickMessage = "&cSent too many packets"; // todo: minimessage ++ public Component kickMessage = Component.translatable("disconnect.exceeded_packet_rate", NamedTextColor.RED); + public PacketLimit allPackets = new PacketLimit(7.0, 500.0, PacketLimit.ViolateAction.KICK); + public Map>, PacketLimit> overrides = Map.of(ServerboundPlaceRecipePacket.class, new PacketLimit(4.0, 5.0, PacketLimit.ViolateAction.DROP)); + @@ -846,6 +847,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import com.mojang.logging.LogUtils; +import io.leangen.geantyref.TypeToken; +import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization; ++import io.papermc.paper.configuration.serializer.ComponentSerializer; +import io.papermc.paper.configuration.serializer.EnumValueSerializer; +import io.papermc.paper.configuration.serializer.FastutilMapSerializer; +import io.papermc.paper.configuration.serializer.PacketClassSerializer; @@ -971,6 +973,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return options.serializers(builder -> builder + .register(MapSerializer.TYPE, new MapSerializer(false)) + .register(new EnumValueSerializer()) ++ .register(new ComponentSerializer()) + ); + } + @@ -2006,6 +2009,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; \ No newline at end of file +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java +@@ -0,0 +0,0 @@ ++package io.papermc.paper.configuration.serializer; ++ ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.minimessage.MiniMessage; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; ++ ++import java.lang.reflect.Type; ++import java.util.function.Predicate; ++ ++public class ComponentSerializer extends ScalarSerializer { ++ ++ public ComponentSerializer() { ++ super(Component.class); ++ } ++ ++ @Override ++ public Component deserialize(Type type, Object obj) throws SerializationException { ++ return MiniMessage.miniMessage().deserialize(obj.toString()); ++ } ++ ++ @Override ++ protected Object serialize(Component component, Predicate> typeSupported) { ++ return MiniMessage.miniMessage().serialize(component); ++ } ++} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -2703,8 +2738,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import io.papermc.paper.configuration.Configuration; +import io.papermc.paper.configuration.serializer.PacketClassSerializer; +import io.papermc.paper.util.ObfHelper; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.format.NamedTextColor; ++import net.kyori.adventure.text.minimessage.MiniMessage; ++import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; ++import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.slf4j.Logger; @@ -2713,6 +2753,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.TransformAction; + ++import java.util.function.Predicate; ++ +import static org.spongepowered.configurate.NodePath.path; + +public final class LegacyPaperConfig { @@ -2867,10 +2909,49 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + moveFromRoot(builder, "proxy-protocol", "proxies"); + ++ miniMessageWithTranslatable(builder, String::isBlank, "multiplayer.disconnect.authservers_down", "messages", "kick", "authentication-servers-down"); ++ miniMessageWithTranslatable(builder, Predicate.isEqual("Flying is not enabled on this server"), "multiplayer.disconnect.flying", "messages", "kick", "flying-player"); ++ miniMessageWithTranslatable(builder, Predicate.isEqual("Flying is not enabled on this server"), "multiplayer.disconnect.flying", "messages", "kick", "flying-vehicle"); ++ miniMessage(builder, "messages", "kick", "connection-throttle"); ++ miniMessage(builder, "messages", "no-permission"); ++ miniMessageWithTranslatable(builder, Predicate.isEqual("&cSent too many packets"), Component.translatable("disconnect.exceeded_packet_rate", NamedTextColor.RED), "packet-limiter", "kick-message"); ++ + return builder.build(); + } + -+ private static void moveFromRootToMisc(final ConfigurationTransformation.Builder builder, String key) { ++ private static void miniMessageWithTranslatable(final ConfigurationTransformation.Builder builder, final Predicate englishCheck, final String i18nKey, final String... strPath) { ++ miniMessageWithTranslatable(builder, englishCheck, Component.translatable(i18nKey), strPath); ++ } ++ private static void miniMessageWithTranslatable(final ConfigurationTransformation.Builder builder, final Predicate englishCheck, final Component component, final String... strPath) { ++ builder.addAction(path((Object[]) strPath), (path, value) -> { ++ final @Nullable Object val = value.raw(); ++ if (val != null) { ++ final String strVal = val.toString(); ++ if (!englishCheck.test(strVal)) { ++ value.set(miniMessage(strVal)); ++ return null; ++ } ++ } ++ value.set(MiniMessage.miniMessage().serialize(component)); ++ return null; ++ }); ++ } ++ ++ private static void miniMessage(final ConfigurationTransformation.Builder builder, final String... strPath) { ++ builder.addAction(path((Object[]) strPath), (path, value) -> { ++ final @Nullable Object val = value.raw(); ++ if (val != null) { ++ value.set(miniMessage(val.toString())); ++ } ++ return null; ++ }); ++ } ++ ++ private static String miniMessage(final String input) { ++ return MiniMessage.miniMessage().serialize(LegacyComponentSerializer.legacySection().deserialize(ChatColor.translateAlternateColorCodes('&', input))); ++ } ++ ++ private static void moveFromRootToMisc(final ConfigurationTransformation.Builder builder, final String key) { + moveFromRoot(builder, key, "misc"); + } +