From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 6 Jun 2019 17:40:30 -0500
Subject: [PATCH] Signs allow color codes


diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 59fa9a9bcfde0a0137fa322343052ed68e47edbe..b13328e1563fa01c141a52bf898ebc520098d0d2 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1464,6 +1464,7 @@ public class ServerPlayer extends Player {
 
     @Override
     public void openTextEdit(SignBlockEntity sign) {
+        if (level.purpurConfig.signAllowColors) this.connection.send(sign.getTranslatedUpdatePacket(textFilteringEnabled)); // Purpur
         sign.setAllowedPlayerEditor(this.getUUID());
         this.connection.send(new ClientboundBlockUpdatePacket(this.level, sign.getBlockPos()));
         this.connection.send(new ClientboundOpenSignEditorPacket(sign.getBlockPos()));
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 41d64ced05f0cfe8e2e9e8f30fb5492c99de6486..e71f9a3256eed2361ac8c5c058ceaeeeabbeefa3 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3072,11 +3072,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
                     }
                 }
                 // Paper end
-                if (this.player.isTextFilteringEnabled()) {
-                    lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(currentLine.getFiltered())));
-                } else {
-                    lines.add(net.kyori.adventure.text.Component.text(SharedConstants.filterText(currentLine.getRaw())));
-                }
+                // Purpur start
+                String line = SharedConstants.filterText(this.player.isTextFilteringEnabled() ? currentLine.getFiltered() : currentLine.getRaw());
+                if (worldserver.purpurConfig.signAllowColors) {
+                    if (player.hasPermission("purpur.sign.color")) line = line.replaceAll("(?i)&([0-9a-fr])", "\u00a7$1");
+                    if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1");
+                    if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1");
+                    lines.add(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line));
+                } else
+                lines.add(net.kyori.adventure.text.Component.text(line));
+                // Purpur end
             }
             SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.player.getBukkitEntity(), lines);
             this.cserver.getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
index 344d3a8c1162f1a4ab5fc2b7676680ddace46649..156a153abe59f86db7f942155d8a21de2fd83ce2 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
@@ -181,6 +181,22 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
         return filtered ? this.filteredMessages : this.messages;
     }
 
+    // Purpur start
+    public ClientboundBlockEntityDataPacket getTranslatedUpdatePacket(boolean filtered) {
+        final CompoundTag nbt = save(new CompoundTag());
+        final Component[] lines = getMessages(filtered);
+        for (int i = 0; i < 4; ++i) {
+            final var component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]);
+            final String line = io.papermc.paper.adventure.PaperAdventure.LEGACY_AMPERSAND.serialize(component);
+            final var text = net.kyori.adventure.text.Component.text(line);
+            final String json = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(text);
+            nbt.putString("Text" + (i + 1), json);
+        }
+        nbt.putString("PurpurEditor", "true");
+        return new ClientboundBlockEntityDataPacket(worldPosition, 9, nbt);
+    }
+    // Purpur end
+
     @Nullable
     @Override
     public ClientboundBlockEntityDataPacket getUpdatePacket() {
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 9541fa2198420001bb471f088be4d46020b0ae3f..982f88df319a3ca239a7364baee22595157d4e43 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -145,8 +145,10 @@ public class PurpurWorldConfig {
         });
     }
 
+    public boolean signAllowColors = false;
     public boolean signRightClickEdit = false;
     private void signSettings() {
+        signAllowColors = getBoolean("blocks.sign.allow-colors", signAllowColors);
         signRightClickEdit = getBoolean("blocks.sign.right-click-edit", signRightClickEdit);
     }
 
